Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JPA default fetch type

Tags:

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?

like image 925
RNJ Avatar asked Apr 12 '12 16:04

RNJ


People also ask

What is the default fetch type in Hibernate?

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.

What is the default fetch type for this initial list is?

Default fetch for collections is "select".

What are the two types of fetch strategies in JPA do you know?

Both FetchType. LAZY and FetchType. EAGER are used to define the default fetch plan.

Is @ManyToOne eager by default?

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.


2 Answers

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.

like image 123
Steve Ebersole Avatar answered Oct 29 '22 17:10

Steve Ebersole


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.

like image 39
Hasan Ceylan Avatar answered Oct 29 '22 17:10

Hasan Ceylan