Defaults: Hibernate Lazy; JPA Eager

Now this is interesting.

We were trying to debug some Hibernate rich objects we had converted from hbm files to annotations, and the objects were blowing up.  One of our more expertish developers with some Hibernate experience insisted that default fetching was lazy.  We decided to accept that as the word and left certain objects with their hbms attributing their failure to annotations not doing something mysterious correctly.

Well, I started to write some unit and integration tests on one of the newer annotated objects and was stubbing the data out with HSQL.  I noticed that there were errors in running the tests of the nature of  failure to hydrate objects.  It smelled like eager fetching. 

So I made the fetching on the many-to-one relationships explicity lazy in an annotation.  I couldn’t believe it.  Searching through the documentation I found this.  Who would have thought that Hibernate and JPA have taken two different approaches!

Fetch strategies and types

In native Hibernate, many-to-one association are lazy by default.
This means that selecting a list of objects with an HQL query will not
initialize the objects at the other end of the many-to-one association.
In JPA the default fetch type is eager (i.e. non-lazy), with separate
selects. This means that any JPAQL query for an entity that has
many-to-one associations in it will result in an N+1 SELECTS problem
even if those associations are not used. To eliminate the unnecessary
queries, simply set the fetch type to LAZY using:

<font color="#000066"><i> @ManyToOne(fetch=FetchType.LAZY)
</i></font>

Then, in any JPA query the association can be eagerly fetched using left join fetch.

Comments are closed.