I came to notice that the default FetchType
for the @ManyToOne
mapping is EAGER
in JPA and Hibernate, whereas for the @OneToMany
mapping, the default FetchType
is LAZY
.
What is the specific reason behind this?
From the JPA 2.0 spec, the defaults are like so:
OneToMany: LAZY
ManyToOne: EAGER
ManyToMany: LAZY
OneToOne: EAGER
And in hibernate, all is Lazy
From Hibernate Docs,
By default, Hibernate uses lazy select fetching for collections and lazy proxy fetching for single-valued associations. These defaults make sense for most associations in the majority of applications.
To answer your question, Hibernate is an implementation of the JPA standard. Hibernate has its own quirks of operation, but as per the Hibernate docs
By default, Hibernate uses lazy select fetching for collections and lazy proxy fetching for single-valued associations. These defaults make sense for most associations in the majority of applications.
So Hibernate will always load any object using a lazy fetching strategy, no matter what type of relationship you have declared.
JPA Spec assumes that in general most of the applications will require the singleton relations by default be eager, whereas multi value relations by default be lazy.
Refer here for more
The reason for setting those to EAGER was because the early JPA 1.0 designers assumed that enforcing JPA implementations to support dynamically initializing Proxies would be a very strong requirement. However, since without Proxies, performance would suffer tremendously, all providers support LAZY associations.
FetchType.EAGER
Using the default EAGER fetching strategy for @ManyToOne
and @OneToOne
associations is a terrible idea as you can easily end up with N+1 query issues.
When using Hibernate, once an association is set to FetchType.EAGER
, you can no longer fetch it lazily at query time. So, you are always going to fetch that relationship whether the current business use case needs it or not.
FetchType.LAZY
by defaultSo, you are better off using FetchType.LAZY
by default for all associations.
Unlike FetchType.EAGER
, a FetchType.LAZY
relationship can be fetched eagerly at query time using a JOIN FETCH
clause.
The only thing you need to be aware of is that you need to fetch a lazy association in the context of the currently running Persistence Context if you need to access the association after the JPA EntityManager
is closed. Otherwise, you are going to get a LazyInitializationException
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With