hibernate映射中的默认提取类型是什么?
探索之后我才知道:
但是在Eclipse中测试后,它渴望所有人。
是否取决于我使用的是JPA还是Hibernate?
答案 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(如果是集合)。如果你考虑一下,你可以得到理由。
单值关联的默认提取是“加入”。
集合的默认提取是“选择”。
请验证最后两行。我从逻辑上推断出来。