简体   繁体   English

Hibernate中一对一,多对一和一对多的默认提取类型

[英]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? hibernate映射中的默认提取类型是什么?

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. 但是在Eclipse中测试之后,它渴望所有人。

Does it depend on whether I am using JPA or Hibernate? 这取决于我使用的是JPA还是Hibernate?

It depends on whether you are using JPA or Hibernate. 这取决于您使用的是JPA还是Hibernate。

From the JPA 2.0 spec , the defaults are: 根据JPA 2.0规范 ,默认值为:

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. 最新版本的Hibernate与上述JPA默认值一致。

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: 我知道在提出这个问题时答案是正确的 - 但是由于人们(像我这一刻)仍然碰巧发现他们为什么他们的WildFly 10的表现不同,我想对当前的Hibernate 5进行更新。 .x版本:

In the Hibernate 5.2 User Guide it is stated in chapter 11.2. Hibernate 5.2用户指南中,它在第11.2节中说明。 Applying fetch strategies : 应用获取策略

The Hibernate recommendation is to statically mark all associations lazy and to use dynamic fetching strategies for eagerness. Hibernate的建议是静态标记所有懒惰的关联,并使用动态提取策略进行渴望。 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 . 遗憾的是,这与JPA规范不一致,该规范定义了默认情况下应该急切地获取所有一对一和多对一关联 Hibernate, as a JPA provider, honors that default. 作为JPA提供者,Hibernate尊重该默认值。

So Hibernate as well behaves like Ashish Agarwal stated above for JPA: 因此,Hibernate的行为与上面针对JPA所述的Ashish Agarwal一样:

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

(see JPA 2.1 Spec ) (见JPA 2.1规范

To answer your question, Hibernate is an implementation of the JPA standard. 为了回答你的问题,Hibernate是JPA标准的一个实现。 Hibernate has its own quirks of operation, but as per the Hibernate docs Hibernate有自己的操作怪癖,但根据Hibernate文档

By default, Hibernate uses lazy select fetching for collections and lazy proxy fetching for single-valued associations. 默认情况下,Hibernate对集合使用延迟选择提取,对单值关联使用延迟代理提取。 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. 因此,无论您声明了什么类型的关系,Hibernate都将使用延迟提取策略加载任何对象。 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 . 应该理解,除非指定fetchType.EAGER ,否则Hibernate将仅在您尝试访问对象时尝试使用值填充这些对象。

For Single valued associations, ie-One-to-One and Many-to-One:- 对于单值关联,即一对一和多对一: -
Default Lazy=proxy 默认Lazy =代理
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. 这意味着仅为关联实体的代理对象加载连接两个实体的id。
Eg: A and B are two entities with Many to one association. 例如:A和B是具有多对一关联的两个实体。 ie: There may be multiple A's for every B. Every object of A will contain a reference of B. 即:每个B可能有多个A.每个A的对象都包含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). 关系A将包含列(辅助,出价,......实体A的其他列)。
The relation B will contain columns(bid,...other columns of entity B) 关系B将包含列(bid,...实体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. 代理意味着在获取A时,仅为B获取id并将其存储到仅包含id的B的代理对象中。 Proxy object of B is a an object of a proxy-class which is a subclass of B with only minimal fields. B的代理对象是代理类的对象,它是B的子类,只有最小字段。 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. 由于出价已经是关系A的一部分,因此没有必要触发查询以从关系B获得出价。实体B的其他属性仅在访问除出价之外的字段时才被延迟加载。

For Collections, ie-Many-to-Many and One-to-Many:- 对于集合,即多对多和一对多: -
Default Lazy=true 默认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). 即:如果lazy ='true'且fetch ='join',则获取A也将获取B或B(如果是集合)。 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. 我从逻辑上推断出。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM