From my understanding @OneToOne
and @ManyToOne
JPA annotations do an eager
fetch. I want these to be lazily loaded in my application, or at least hint at it (which is what hibernate defaults to). I have started to add the annotation fetch = FetchType.LAZY
eg
@ManyToOne(optional = false, fetch = FetchType.LAZY)
instead of
@ManyToOne(optional = false)
This is both tedious and error prone. Is there a way I can do this at an application level? In the persistence.xml perhaps?
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. If you set hibernate. default_batch_fetch_size , Hibernate will use the batch fetch optimization for lazy fetching.
Default fetch for collections is "select".
Both FetchType. LAZY and FetchType. EAGER are used to define the default fetch plan.
By default, the JPA @ManyToOne and @OneToOne annotations are fetched EAGERly, while the @OneToMany and @ManyToMany relationships are considered LAZY. This is the default strategy, and Hibernate doesn't magically optimize your object retrieval, it only does what is instructed to do.
To date, I have chosen to have Hibernate follow the JPA spec in terms of mapping via annotations simply because I have not received any feature requests for making it configurable, which was surprising TBH. As you point out, since Hibernate 3.0 what you want has been the default set up when using hbm.xml
mapping files.
Allowing this via configuration would not violate the spec as another answer suggested.
So long story short, no it is not possible today. Create a feature request if you'd like to see that be configurable.
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. And at least in my own experience, this is generally the desired architecture. This makes sense, since singleton relations require no significant additional performance in JPA layer and DB layer to create a singleton join on foreign key. However, in contradiction to that, multi valued attributes create either N + 1 problem or large cartesian resultsets that get inflates exponentially as the number of elements in collections and number of joins increase when join fetch is used (Although Hibernate specifically cannot handle join fetches on 2+ eager associations).
Having said that, as for your suggestion, you require a specific (to be honest not completely uncommon) case to be addressed. Now you have a single case but as there are hundreds of cases like that. So to write specifications you need to draw a line between the generalization and granularity.
If I were in your shoes, if you think this an absolutely useful feature to be added to JPA Specification, I would submit it to the JCP. On the other hand if you get this(, that and that...) addressed in a specific implementation then you end up in so-called vendor-lockin. So I would work an extra hour to set the lazy fetch on @ManyToOne @OneToOne attributes and stay vendor-free, therefore by sticking to the specification if say a new JPA implementation comes along that is over 15x faster then Hibernate (or whatever implementation you use), it would take little to no effort to move your project that new JPA implementation.
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