Hibernate version: 3.6.1.FINAL
This is a HOW TO Eager loading a many-to-many association with Criteria, because i don't find it easily on google.
I use Work/Authors/Persons
example of the hibernate documentation.
I try to load all Work from specifics authors with a eager loading of the authors.
According to the
chapter 20.1.2 of the hibernate documentation, the code is:
Code:
Criteria criteria = session.createCriteria(Work.class);
criteria.add(Restrictions.eq("title", "First Title"));
criteria.setFetchMode("authors", FetchMode.JOIN);
List<Work> list = criteria.list();
Set<Author> authors = list.get(0).getAuthors();\\I am sure there is one work
for (Author author : authors) {
System.out.println(author.getAlias());
}
All works, a single query is generated.
But if i add a restrictions to the authors like
Code:
criteria.createCriteria("authors").add(Restrictions.like("alias", "%author%"));
hibernate generates 2 queries:
Code:
Hibernate: select this_.id as id0_1_, this_.title as title0_1_, this_.text as text0_1_, this_.tempo as tempo0_1_, this_.genre as genre0_1_, this_.type as type0_1_, authors3_.work_id as work1_0_, author1_.id as author2_, author1_.id as id2_0_, author1_.alias as alias2_0_ from works this_ inner join author_work authors3_ on this_.id=authors3_.work_id inner join authors author1_ on authors3_.author_id=author1_.id where this_.title=? and author1_.alias like ?
Hibernate: select authors0_.work_id as work1_0_1_, authors0_.author_id as author2_1_, author1_.id as id2_0_, author1_.alias as alias2_0_ from author_work authors0_ inner join authors author1_ on authors0_.author_id=author1_.id where authors0_.work_id=?
The Fetch Mode doesn't seem to work. The workaround is to use
criteria.createCriteria(String associationPath,int join) like:
Code:
Criteria criteria = session.createCriteria(Work.class);
criteria.add(Restrictions.eq("title", "First Title"));
criteria.createCriteria("authors",CriteriaSpecification.LEFT_JOIN).add(Restrictions.like("alias", "%author%"));
and so hibernate generates 1 query:
Code:
Hibernate:
select
this_.id as id0_1_,
this_.title as title0_1_,
this_.text as text0_1_,
this_.tempo as tempo0_1_,
this_.genre as genre0_1_,
this_.type as type0_1_,
authors3_.work_id as work1_0_3_,
author1_.id as author2_3_,
author1_.id as id2_0_,
author1_.alias as alias2_0_
from
works this_
left outer join
author_work authors3_
on this_.id=authors3_.work_id
left outer join
authors author1_
on authors3_.author_id=author1_.id
where
this_.title=?
and author1_.alias like ?
To resume, if you want to eager loading an association:
- If you need a restriction on this association, use criteria.createCriteria(String associationPath,CriteriaSpecification.LEFT_JOIN)
- Else use criteria.setFetchMode("authors", FetchMode.JOIN);
For Hibernate seniors and developpers: Is it possible to have only one way to do this?
Thanks