这取决于您使用的是 JPA 还是 Hibernate。
从 JPA 2.0 spec 开始,默认值为:
OneToMany: LAZY
ManyToOne: EAGER
ManyToMany: LAZY
OneToOne: EAGER
在休眠状态下,一切都是懒惰的
更新:
最新版本的 Hibernate 与上述 JPA 默认值一致。
我知道在提出问题时答案是正确的 - 但是由于人们(就像我现在一样)仍然碰巧发现他们想知道为什么他们的 WildFly 10 表现不同,我想提供当前 Hibernate 5 的更新.x 版本:
在 Hibernate 5.2 User Guide 中,它在第 11.2 章中有说明。应用获取策略:
Hibernate 的建议是将所有关联静态标记为惰性,并使用动态获取策略来实现渴望。不幸的是,这与 JPA 规范不一致,该规范定义了所有一对一和多对一的关联都应该在默认情况下急切地获取。 Hibernate,作为一个 JPA 提供者,尊重这个默认值。
因此,Hibernate 的行为也类似于上面针对 JPA 所述的 Ashish Agarwal:
OneToMany: LAZY
ManyToOne: EAGER
ManyToMany: LAZY
OneToOne: EAGER
(见JPA 2.1 Spec)
为了回答您的问题,Hibernate 是 JPA 标准的一种实现。 Hibernate 有自己的操作怪癖,但根据 Hibernate docs
默认情况下,Hibernate 对集合使用惰性选择获取,对单值关联使用惰性代理获取。这些默认值对于大多数应用程序中的大多数关联都是有意义的。
因此 Hibernate 将始终使用延迟获取策略加载任何对象,无论您声明了哪种类型的关系。它将为一对一或多对一关系中的单个对象使用惰性代理(应该未初始化但不为空),以及一个空集合,当您尝试访问它时它将与值水合.
应该理解,Hibernate 只会在您尝试访问对象时尝试用值填充这些对象,除非您指定 fetchType.EAGER
。
对于单值关联,即一对一和多对一:- 默认 Lazy=proxy 代理延迟加载:- 这意味着您的关联实体的代理对象已加载。这意味着只为关联实体的代理对象加载连接两个实体的 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 将包含列(aid,bid,...实体 A 的其他列)。关系 B 将包含列(出价,...实体 B 的其他列) 代理意味着当获取 A 时,仅获取 B 的 id 并存储到 B 的仅包含 id 的代理对象中。 B 的代理对象是代理类的对象,它是 B 的子类,只有最少的字段。由于bid 已经是关系A 的一部分,因此不必触发查询以从关系B 中获取bid。实体B 的其他属性仅在访问bid 以外的字段时才延迟加载。
对于集合,即多对多和一对多:- 默认 Lazy=true 另请注意,获取策略(选择、加入等)可以覆盖惰性。即:如果lazy='true' 和fetch='join',则获取A 也会获取B 或Bs(如果是集合)。仔细想想就知道原因了。单值关联的默认获取是“join”。集合的默认获取是“选择”。请验证最后两行。我已经从逻辑上推断出来了。