Iterating through relations – single query

Scenario

There is still the same problem but we solve it with a different query.

Solution

With join fetch we can tell Hibernate to load associations immediately. Hibernate will use a single SQL select which joins the chapters to the book table.

List<Book> books = session.createQuery(
   "select b from Book b left join fetch b.chapters where b.name like ?")
   .setString(0, "Java%")
   .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY).list();

The same with a criteria query:

List<Book> books = session.createCriteria(Book.class)
   .setFetchMode("chapters", org.hibernate.FetchMode.JOIN)
   .add(Restrictions.like("name", "Java", MatchMode.START))
   .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY).list();

The performance is very good but we must be aware that we will load all chapters into memory. Finally, don’t use join fetch with multiple collections, you will create a rapidly growing Cartesian product. A join will combine all possible combinations. Let’s do a SQL join on data where every book have two chapters and two comments.

select * from book b left join chapters c on b.id=c.book_id left join comment cm on b.id=cm.book_id

Book idOther book columnsChapter idOther chapter columnsComment idOther comment columns

1

2

2

1

1

1

1

1

2

1

2

1