ChatGPT解决这个技术问题 Extra ChatGPT

Default fetch type for one-to-one, many-to-one and one-to-many in Hibernate

What is the default fetch type in hibernate mappings?

What I got to know after exploring is:

for one-to-one it is eager.

for one-to-many it is lazy.

But after testing it in Eclipse, it was eager for all.

Does it depend on whether I am using JPA or Hibernate?

In case you're still involved in JPA topics - I updated your question with a new answer, since the old ones are outdated for the current Hibernate version.

A
Alexander Rühl

It depends on whether you are using JPA or Hibernate.

From the JPA 2.0 spec, the defaults are:

OneToMany: LAZY
ManyToOne: EAGER
ManyToMany: LAZY
OneToOne: EAGER

And in hibernate, all is Lazy

UPDATE:

The latest version of Hibernate aligns with the above JPA defaults.


"And in hibernate, all is Lazy" apparently it has changed in recent versions. Please see Alexander Rühl's answer below.
Hibernate is one of JPA implementations, so once you're using Hibernate, you're using JPA :)
This is a popular query. @Ashish Agarwal Can you please update the last line of your answer. In Hibernate its not Lazy for all now.
Updated the post with regards to latest Hibernate behavior.
There was an update, claiming that eager is default fetch type for every mapping, which is rebuted by chapter 11.3 in both current 5.x and new 6.x Hibernate documentation, so I undid the edit. Besides, it is against the recommendation to not have automatic eagerness, since this would mean to probably select the whole database when fetching a single object.
A
Alexander Rühl

I know the answers were correct at the time of asking the question - but since people (like me this minute) still happen to find them wondering why their WildFly 10 was behaving differently, I'd like to give an update for the current Hibernate 5.x version:

In the Hibernate 5.2 User Guide it is stated in chapter 11.2. Applying fetch strategies:

The Hibernate recommendation is to statically mark all associations lazy and to use dynamic fetching strategies for eagerness. This is unfortunately at odds with the JPA specification which defines that all one-to-one and many-to-one associations should be eagerly fetched by default. Hibernate, as a JPA provider, honors that default.

So Hibernate as well behaves like Ashish Agarwal stated above for JPA:

OneToMany: LAZY
ManyToOne: EAGER
ManyToMany: LAZY
OneToOne: EAGER

(see JPA 2.1 Spec)


And what if we use the native hibernate instead of JPA impl, do it act the same way ?
@jMounir: Well, I haven't tried that, but since Hibernate states that it behaves like defined in JPA, I don't see why that would differ when using Hibernate for itself. One can in both cases override the default strategy.
J
JamesENL

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. It will use a lazy proxy (which should be uninitialized but not null) for a single object in a one-to-one or many-to-one relationship, and a null collection that it will hydrate with values when you attempt to access it.

It should be understood that Hibernate will only attempt to fill these objects with values when you attempt to access the object, unless you specify fetchType.EAGER.


J
Jijo Mathew

For Single valued associations, i.e.-One-to-One and Many-to-One:- Default Lazy=proxy Proxy lazy loading:- This implies a proxy object of your associated entity is loaded. This means that only the id connecting the two entities is loaded for the proxy object of associated entity. Eg: A and B are two entities with Many to one association. ie: There may be multiple A's for every B. Every object of A will contain a reference of B. `

public class A{
    int aid;
    //some other A parameters;
    B b;
}
public class B{
    int bid;
     //some other B parameters;
}

` The relation A will contain columns(aid,bid,...other columns of entity A). The relation B will contain columns(bid,...other columns of entity B) Proxy implies when A is fetched, only id is fetched for B and stored into a proxy object of B which contains only id. Proxy object of B is a an object of a proxy-class which is a subclass of B with only minimal fields. Since bid is already part of relation A, it is not necessary to fire a query to get bid from the relation B. Other attributes of entity B are lazily loaded only when a field other than bid is accessed.

For Collections, i.e.-Many-to-Many and One-to-Many:- Default Lazy=true Please also note that the fetch strategy(select,join etc) can override lazy. ie: If lazy='true' and fetch='join', fetching of A will also fetch B or Bs(In case of collections). You can get the reason if you think about it. Default fetch for single valued association is "join". Default fetch for collections is "select". Please verify the last two lines. I have deduced that logically.