【发布时间】:2014-12-23 10:14:31
【问题描述】:
hibernate 映射中的默认获取类型是什么?
我在探索之后了解到的是:
- 对于一对一来说,它是渴望。
- 对于一对多,它是 惰性。
但在 Eclipse 中测试后,它对所有人都渴望。
这取决于我使用的是 JPA 还是 Hibernate?
【问题讨论】:
-
如果您仍然参与 JPA 主题 - 我用新答案更新了您的问题,因为旧答案对于当前的 Hibernate 版本已经过时。
hibernate 映射中的默认获取类型是什么?
我在探索之后了解到的是:
但在 Eclipse 中测试后,它对所有人都渴望。
这取决于我使用的是 JPA 还是 Hibernate?
【问题讨论】:
这取决于您使用的是 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。
【讨论】:
对于单值关联,即一对一和多对一:-
默认懒惰=代理
代理延迟加载:- 这意味着您的关联实体的代理对象已加载。这意味着只为关联实体的代理对象加载连接两个实体的 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 将包含列(出价,...实体 B 的其他列)
代理意味着当获取 A 时,仅获取 B 的 id 并存储到 B 的仅包含 id 的代理对象中。
B 的代理对象是代理类的对象,它是 B 的子类,只有最少的字段。
由于 bid 已经是关系 A 的一部分,因此不必触发查询来从关系 B 中获取 bid。
实体 B 的其他属性只有在访问 bid 以外的字段时才会延迟加载。
对于集合,即多对多和一对多:-
默认懒惰=真
另请注意,获取策略(选择、加入等)可以覆盖惰性。
即:如果lazy='true' 和fetch='join',则获取A 也会获取B 或Bs(如果是集合)。仔细想想就知道原因了。
单值关联的默认获取是“加入”。
集合的默认提取是“选择”。
请验证最后两行。我已经从逻辑上推断出来了。
【讨论】: