为什么@ManyToOne关系默认为JPA FetchType EAGER?

vat*_*ada 12 java orm hibernate jpa hibernate-mapping

我在Hibernate源代码中注意到,ManyToOne映射的默认FetchType是EAGER.而OnetoMany映射的默认加载类型是Lazy.这背后的具体原因是什么?

Ank*_*hal 27

JPA 2.0 spe c,默认值如下:

OneToMany: LAZY
ManyToOne: EAGER
ManyToMany: LAZY
OneToOne: EAGER
Run Code Online (Sandbox Code Playgroud)

休眠中,一切都是懒惰的

来自Hibernate Docs,

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

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

By default, Hibernate uses lazy select fetching for collections and lazy proxy fetching for single-valued associations. These defaults make sense for most associations in the majority of applications.
Run Code Online (Sandbox Code Playgroud)

因此,无论您声明了什么类型的关系,Hibernate都将使用延迟提取策略加载任何对象.

JPA Spec假设通常大多数应用程序默认需要单例关系,而默认情况下多值关系是惰性的.

请参阅此处了解更多

  • “因此,Hibernate 将始终使用惰性获取策略加载任何对象,无论您声明了哪种类型的关系。” 不正确,因为 Hibernate 在我使用 ManyToOne 映射的代码中使用 EAGER 策略加载。并且在 hibernate 源中默认 Fetch 类型设置为 EAGER。 (2认同)

Vla*_*cea 6

将这些设置为EAGER的原因是因为早期的JPA 1.0设计者认为强制执行JPA实现以支持动态初始化代理将是一个非常强烈的要求.但是,由于没有Proxies,性能会受到很大影响,所有提供商都支持LAZY关联.

使用默认的EAGER提取策略@ManyToOne@OneToOne关联是代码气味.

本文所述,我建议您将所有关联设置为LAZY,并使用每个HQL/JPQL或Criteria查询中提供的JOIN FETCH指令.

  • 除了许多 JPA 提供者不使用单值关系的“代理”之外。 (2认同)