25.6.1. Fetching associations
<div class="paragraph">
Related to associations, there are two major fetch strategies:
</div>
<div class="ulist">
EAGER
LAZY
</div>EAGER
fetching is almost always a bad choice.</div>
</td>
Prior to JPA, Hibernate used to have all associations as
LAZY
by default. However, when JPA 1.0 specification emerged, it was thought that not all providers would use Proxies. Hence, the@ManyToOne
and the@OneToOne
associations are nowEAGER
by default.</div>
The
EAGER
fetching strategy cannot be overwritten on a per query basis, so the association is always going to be retrieved even if you don’t need it. More, if you forget toJOIN FETCH
anEAGER
association in a JPQL query, Hibernate will initialize it with a secondary statement, which in turn can lead to N+1 query issues.</div> </td> </tr> </table> </div>
So,
EAGER
fetching is to be avoided. For this reason, it’s better if all associations are marked asLAZY
by default.</div>
However,
LAZY
associations must be initialized prior to being accessed. Otherwise, aLazyInitializationException
is thrown. There are good and bad ways to treat theLazyInitializationException
.</div>
The best way to deal with
LazyInitializationException
is to fetch all the required associations prior to closing the Persistence Context. TheJOIN FETCH
directive is good for@ManyToOne
andOneToOne
associations, and for at most one collection (e.g.@OneToMany
or@ManyToMany
). If you need to fetch multiple collections, to avoid a Cartesian Product, you should use secondary queries which are triggered either by navigating theLAZY
association or by callingHibernate#initialize(proxy)
method.</div> </div> </div>