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


103

休眠映射中的默认访存类型是什么?

探索后我知道的是:

  • 渴望一对一。
  • 对于一对多来说,这是懒惰的

但是在Eclipse中对其进行测试后,它对所有人都非常渴望。

是否取决于我使用的是JPA还是Hibernate?


1
如果您仍然参与JPA主题-我用新的答案更新了您的问题,因为旧的版本在当前的Hibernate版本中已经过时了。
亚历山大·吕尔

Answers:


193

这取决于您使用的是JPA还是Hibernate。

根据JPA 2.0规范,默认值为:

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

冬眠的时候,一切都是懒惰的

更新:

最新版本的Hibernate符合上述JPA默认设置。


11
“并且在休眠状态下,一切都是惰性的”显然在最新版本中已更改。请在下面查看AlexanderRühl的回答
Dinei '17

1
Hibernate是JPA的实现之一,因此,一旦使用Hibernate,就使用JPA :)
xenteros

这是一个流行的查询。@Ashish Agarwal您能否更新答案的最后一行。在Hibernate中,目前还不懒惰。
萨拉·蒂瓦里

更新了有关最新Hibernate行为的帖子。
M Anouti

有一个更新,声称急切是每个映射的默认获取类型,在当前的5.x和新的6.x Hibernate文档中,第11.3章都驳斥了该类型,因此我取消了编辑。此外,不建议您不要具有自动渴望性,因为这将意味着在获取单个对象时可能选择整个数据库。
亚历山大·吕尔

51

我知道在提出问题时答案是正确的-但由于人们(此刻与我一样)仍然发现他们想知道为什么WildFly 10的行为方式有所不同,所以我想对当前的Hibernate 5进行更新.x版本:

Hibernate 5.2用户指南》在第11.2章中进行了说明应用提取策略

Hibernate的建议是静态地标记所有懒惰的关联,并使用动态获取策略来提高渴望。不幸的是,这与JPA规范不一致,该规范定义 默认情况下应热切获取所有一对一和多对一关联。作为JPA提供程序,Hibernate遵守默认设置。

因此,Hibernate的行为也类似于上面针对JPA所述的Ashish Agarwal:

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

(请参阅JPA 2.1规范


如果我们使用本机休眠而不是JPA impl,它会以同样的方式起作用吗?
jMounir

@jMounir:好吧,我还没有尝试过,但是由于Hibernate声明它的行为就像JPA中定义的那样,所以我不明白为什么在自己使用Hibernate时会有所不同。在两种情况下,一个都可以覆盖默认策略。
亚历山大·吕尔

15

为了回答您的问题,Hibernate是JPA标准的实现。Hibernate有其自己的操作怪癖,但根据Hibernate文档

默认情况下,Hibernate对集合使用延迟选择获取,对单值关联使用延迟代理获取。对于大多数应用程序中的大多数关联而言,这些默认设置有意义。

因此,无论您声明了什么类型的关系,Hibernate都将始终使用惰性获取策略加载任何对象。它将以一对一或多对一关系为单个对象使用惰性代理(应该未初始化,但不能为null),并使用null集合,当您尝试访问它时它将与值混合。

应该理解的是,除非您指定,否则Hibernate仅在尝试访问对象时才尝试用值填充这些对象 fetchType.EAGER


0

对于单值关联,即一对一和多对一:-
默认Lazy = proxy
代理延迟加载:-这表示已加载关联实体的代理对象。这意味着,仅将连接两个实体的id加载给关联实体的代理对象。
例如:A和B是两个具有多对一关联的实体。即:有可能是多个A对A的每个B.每个对象将包含B的参考
`

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

`
的关系将包含列(援助,竞价...实体A的其他列)。
关系B将包含列(出价,...,实体B的其他列)

代理暗含当获取A时,仅为B提取id并存储到仅包含id的B代理对象中。B的代理对象是代理类的对象,该代理类是B的子类,只有很少的字段。由于出价已经是关系A的一部分,因此无需触发查询即可从关系B获取出价。实体B的其他属性仅在访问除出价以外的字段时才被延迟加载。

对于集合,即“多对多”和“一对多”:-
默认Lazy = true


请注意,获取策略(选择,联接等)可以覆盖惰性。即:如果lazy ='true'和fetch ='join',则A的获取也将获取B或Bs(对于集合)。考虑一下就可以找到原因。
单值关联的默认访存是“ join”。
集合的默认获取是“选择”。请验证最后两行。我已经从逻辑上推论了这一点。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.