25.6.1. Fetching associations
<div class="paragraph">
Related to associations, there are two major fetch strategies:
</div>
<div class="ulist">
EAGERLAZY</div>EAGERfetching is almost always a bad choice.</div>
</td>
Prior to JPA, Hibernate used to have all associations as
LAZYby default. However, when JPA 1.0 specification emerged, it was thought that not all providers would use Proxies. Hence, the@ManyToOneand the@OneToOneassociations are nowEAGERby default.</div>
The
EAGERfetching 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 FETCHanEAGERassociation 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,
EAGERfetching is to be avoided. For this reason, it’s better if all associations are marked asLAZYby default.</div>
However,
LAZYassociations must be initialized prior to being accessed. Otherwise, aLazyInitializationExceptionis thrown. There are good and bad ways to treat theLazyInitializationException.</div>
The best way to deal with
LazyInitializationExceptionis to fetch all the required associations prior to closing the Persistence Context. TheJOIN FETCHdirective is good for@ManyToOneandOneToOneassociations, and for at most one collection (e.g.@OneToManyor@ManyToMany). If you need to fetch multiple collections, to avoid a Cartesian Product, you should use secondary queries which are triggered either by navigating theLAZYassociation or by callingHibernate#initialize(proxy)method.</div> </div> </div>