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

时间:2014-10-28 04:44:10

标签: java hibernate jpa

hibernate映射中的默认提取类型是什么?

探索之后我才知道:

  • 一对一,渴望
  • 对于一对多,懒惰

但是在Eclipse中测试后,它渴望所有人。

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

4 个答案:

答案 0 :(得分:143)

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

JPA 2.0 spec开始,默认值为:

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

在休眠状态下,一切都是懒惰的

<强>更新

最新版本的Hibernate与上述JPA默认值保持一致。

答案 1 :(得分:49)

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

Hibernate 5.2 User Guide中,在 11.2章节中说明了这一点。应用提取策略

  

Hibernate的建议是静态标记所有关联   懒惰,并使用动态提取策略进行渴望。这是   不幸的是与JPA规范不一致,后者定义了这一点   应该热切地提取所有一对一和多对一的关联   默认情况下。作为JPA提供者,Hibernate尊重该默认值。

所以Hibernate的行为与上面提到的JPA的Ashish Agarwal一样:

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

(见JPA 2.1 Spec

答案 2 :(得分:15)

为了回答你的问题,Hibernate是JPA标准的一个实现。 Hibernate有自己的操作怪癖,但按照Hibernate docs

  

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

因此,无论您声明了什么类型的关系,Hibernate都会使用延迟抓取策略加载任何对象。对于一对一或多对一关系中的单个对象,它将使用惰性代理(对于未初始化但不为空),以及当您尝试访问它时,它将使用值进行水合的空集合。

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

答案 3 :(得分:0)

对于单值关联,即一对一和多对一: -
默认Lazy =代理
代理延迟加载: - 这意味着已加载关联实体的代理对象。这意味着仅为关联实体的代理对象加载连接两个实体的id。
例如:A和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;
}

`
关系A将包含列(辅助,出价,......实体A的其他列) 关系B将包含列(bid,......实体B的其他列)
代理意味着在获取A时,仅为B获取id并将其存储到仅包含id的B的代理对象中。 B的代理对象是代理类的对象,它是B的子类,只有最小字段。 由于出价已经是关系A的一部分,因此无需触发查询以从关系B中获取出价。 只有当访问了出价以外的字段时,才会延迟加载实体B的其他属性。

对于收藏,即多对多和一对多: -
默认Lazy = true


另请注意,获取策略(选择,加入等)可以覆盖延迟。 即:如果lazy ='true'且fetch ='join',则获取A也将获取B或B(如果是集合)。如果你考虑一下,你可以得到理由。
单值关联的默认提取是“加入”。
集合的默认提取是“选择”。 请验证最后两行。我从逻辑上推断出来。