I have a category entity that has a category as parent and a list of category as child. here’s it’s declaration:
@Entity
@Table(name="CATEGORYENTITY")
public class CategoryEntity extends BaseEntity<Long> {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue
@Column(name="ID")
private Long id;
@Column(name="NAME")
private String name;
@Column(name="VIEWSCOUNT")
private Integer viewsCount;
@OneToMany(fetch=FetchType.EAGER, cascade={CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH})
@Cascade(org.hibernate.annotations.CascadeType.SAVE_UPDATE)
@JoinColumn(name="CATEGORY_ID")
private List<CategoryEntity> childCategories;
@ManyToOne(fetch=FetchType.EAGER)
@JoinColumn(name="CATEGORY_ID")
private CategoryEntity parent;
setters and getters...
It works fine when saving and updating but when try to get all of the categories… for each child returns a parent too!!! I mean if i have a mainCat and this mainCat has 4 child for example, when getting all categories from db, it returns all of the four child and surprisingly 4 mainCat… the weird part is that returned objects are correct and their properties are set correct and 4 mainCat are same!!! what should I do?
I use following code to retrieve results:
public List<E> find(E example, final PagingObject paging, Map<?, ?> filter) throws Exception {
// create the criteria
final DetachedCriteria detachedCriteria = createCriteria(filter);
// add restrictions to the criteria based on example entity
pruneCriteria(detachedCriteria, example);
List<E> result = getHibernateTemplate().execute(new HibernateCallback<List<E>>() {
@SuppressWarnings("unchecked")
@Override
public List<E> doInHibernate(Session session) throws HibernateException, SQLException {
// attach criteria to the session
Criteria criteria = detachedCriteria.getExecutableCriteria(session);
// add paging and sort to the criteria
paginate(criteria, paging);
List<E> list = criteria.list();
return list;
}
});
return result;
}
A bidirectional association always has an owner side, and an inverse side. The owner side is the one where you define how the association is mapped (using @JoinColumn). On the inverse side, you must not define how the association is mapped (it would be redundant). But you must define that it’s the inverse side by using the mappedBy attribute.
Instead of defining a parent-child bidirectional association, you have defined two different associations.
The mapping of the collection should be:
Note that setting both sides of such an association as EAGER will force Hibernate to load the whole tree each time you load one single node of the tree. Prepare yourself for a very large number of queries to be executed, and abysmal performance.