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

在休眠映射中,默认的提取类型是什么?

在探索之后我了解到的是:

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

但是在 Eclipse 中测试之后,它渴望所有人都参与进来。

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

153640 次浏览

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

默认情况下,Hibernate 对集合使用惰性选择获取,对单值关联使用惰性代理获取。对于大多数应用程序中的大多数关联来说,这些默认值是有意义的。

因此,Hibernate 将始终使用延迟抓取策略加载任何对象,无论您声明了什么类型的关系。对于一对一或多对一关系中的单个对象,它将使用一个惰性代理(应该是未初始化的,但不是 null) ,以及一个 null 集合,当您试图访问它时,它将使用这些值。

应该理解,Hibernate 只会在您尝试访问对象时尝试用值填充这些对象,除非您指定 fetchType.EAGER

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

JPA 2.0规范来看,默认值是:

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

在冬眠中,一切都是懒惰

更新:

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

我知道在问这个问题的时候答案是正确的——但是因为人们(比如此刻的我)仍然碰巧发现他们想知道为什么他们的 WildFly 10表现的不同,我想给出一个最新的 Hibernate 5.x 版本:

Hibernate 5.2用户指南中,11.2. 应用提取策略章阐明:

Hibernate 建议静态标记所有关联 懒惰并使用动态获取策略来满足渴望 不幸的是,它与 JPA 规范不一致,JPA 规范定义了 所有一对一和多对一的关联都应该被急切地获取 在默认情况下 . Hibernate 作为 JPA 提供程序遵循这一默认值

所以 Hibernate 也像上面提到的 Ashish Agarwal 为 JPA 所做的那样:

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

(见 JPA 2.1规范)

对于单值关联,即-一对一和多对一:-
默认惰性 = 代理
代理延迟加载 :-这意味着加载了关联实体的代理对象。这意味着只有连接两个实体的 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 的列(aid、 id、 ... ... 其他列)。
关系 B 将包含列(出价,... 实体 B 的其他列)

代理意味着当获取 A 时,只为 B 获取 id 并存储到只包含 id 的 B 的代理对象中。 B 的代理对象是代理类的一个对象,代理类是 B 的一个子类,只有极小的字段。 因为出价已经是关系 A 的一部分,所以没有必要触发一个查询来从关系 B 获得出价。 实体 B 的其他属性只有在访问出价以外的字段时才延迟加载。

对于集合,即-多对多和一对多:-
默认懒 = 真


还请注意,提取策略(select、 join 等)可以覆盖惰性。 例如: 如果惰性 = ‘ true’和 fetch= ‘ join’,那么 A 的抓取也将获取 B 或 B (在集合的情况下)。仔细想想就知道原因了。
单值关联的默认提取是“ join”。
集合的默认获取是“ select”。 请证实最后两行。我已经推断出逻辑。