I have News class that has the many-to-many relationship with Category class, i.e. a news belongs to one on more categories. I need to find all the news that belong to the specified category and then show on the page news description and all its categories.
Hibernate version: 3.1.3
The category class and its mapping are described in my post at
http://forum.hibernate.org/viewtopic.php?t=964248. Here is
Mapping document for the News class:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="by.hibernate.app.model.News" table="NEWS">
<id name="id" column="NEWS_ID">
<generator class="native"/>
</id>
<property name="description" column="DESCRIPTION"/>
<property name="text" column="text" type="text"/>
<set name="categories" table="NEWS_CATEGORY">
<key column="NEWS_ID"/>
<many-to-many class="by.hibernate.app.model.Category" column="CATEGORY_ID"/>
</set>
</class>
</hibernate-mapping>
The News class:
package by.hibernate.app.model;
import java.io.Serializable;
import java.util.Set;
import java.util.HashSet;
public class News implements Serializable {
private Long id;
private String description;
private Set categories = new HashSet();
private String text;
public News() {
}
public News(String description, String text) {
this.description = description;
this.text = text;
}
public News(String description, Set categories, String text) {
this.description = description;
this.categories = categories;
this.text = text;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Set getCategories() {
return categories;
}
public void setCategories(Set categories) {
this.categories = categories;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
}
I tried to achive that with the Criteria API:
Code between sessionFactory.openSession() and session.close():
Criteria criteria = session.createCriteria(News.class);
criteria.setFetchMode("categories", FetchMode.JOIN);
Criteria innerCriteria = criteria.createCriteria("categories");
innerCriteria.add(Expression.eq("id", dellLaptop.getId()));
HashSet result = new HashSet(criteria.list());
I got the correct selection. However the News object has the uninitialized categories collection (throws LazyInitializationException). I was supprised to find out that it depends somehow on the type of join of the sub-criteria. The following code returns the initialized categories:
Criteria innerCriteria = criteria.createCriteria("categories", CriteriaSpecification.LEFT_JOIN);
Whereas the followings don't:
Criteria innerCriteria = criteria.createCriteria("categories", CriteriaSpecification.JOIN);
Criteria innerCriteria = criteria.createCriteria("categories", CriteriaSpecification.FULL_JOIN);
It looks like a bug in Hibernate.
Any thoughts?