Java JPA默认获取类型

Java JPA默认获取类型,java,hibernate,jpa,fetch,Java,Hibernate,Jpa,Fetch,据我所知,JPA注释执行一个急切的获取。我希望在我的应用程序中惰性地加载这些文件,或者至少提示它(这是hibernate的默认设置)。我已经开始添加注释fetch=FetchType.LAZY 乙二醇 而不是 @ManyToOne(optional = false) 这既单调又容易出错。有没有一种方法可以在应用程序级别实现这一点?也许在persistence.xml中?不可能。在JPA规范中没有关于更改全局抓取策略的内容。JPA为1-1/N-1关联提供了即时抓取,而对于1-N/M-N则是惰性的

据我所知,JPA注释执行一个
急切的
获取。我希望在我的应用程序中惰性地加载这些文件,或者至少提示它(这是hibernate的默认设置)。我已经开始添加注释
fetch=FetchType.LAZY

乙二醇

而不是

@ManyToOne(optional = false)

这既单调又容易出错。有没有一种方法可以在应用程序级别实现这一点?也许在persistence.xml中?

不可能。在JPA规范中没有关于更改全局抓取策略的内容。JPA为1-1/N-1关联提供了即时抓取,而对于1-N/M-N则是惰性的。所有JPA实现都应遵循规范以符合要求。我认为,最好是应用程序开发人员不能全局更改此默认beheavior,因为在几乎大多数情况下,这些都是最佳实践,除非所有实体之间只有一种类型的关联,如1-1。考虑一下,您可以在应用程序中将其设置为“渴望”,该应用程序包含一个真正丰富的实体模型,其中包含复杂的关系和数据库中数百万的数据。手动覆盖每个关联的抓取策略允许开发人员负责接下来发生的事情。它不容易出错,而是一个强大的功能

到目前为止,我选择让Hibernate在通过注释进行映射方面遵循JPA规范,这仅仅是因为我没有收到任何使其可配置的功能请求,这令人惊讶。正如您所指出的,自Hibernate 3.0以来,在使用
hbm.xml
映射文件时,您需要的是默认设置

正如另一个答案所建议的那样,允许这种通过配置不会违反规范

长话短说,不,这在今天是不可能的。如果您希望看到功能请求是可配置的,请创建一个功能请求

根据我的理解,@oneToOne和@ManyToOne JPA注释 急切的费奇


JPA保证在单值关系上快速加载,如果不是通过注释或在持久性XML中声明的话。对于集合值关系,它默认为延迟加载,但延迟加载(只是)对支持JPA的持久性提供程序的提示,因此您不能依赖它,必须检查特定的提供程序(例如Hibernate、OpenJPA)。请参阅作为参考,以获取更多信息。

JPA规范假定,通常大多数应用程序都要求默认情况下的单值关系是“渴望”,而默认情况下的多值关系是“懒惰”。至少根据我自己的经验,这通常是理想的架构。这是有意义的,因为在JPA层和DB层中,单例关系不需要显著的额外性能来创建外键上的单例联接。然而,与此相反,多值属性创建了N+1问题或大型笛卡尔结果集,当使用联接获取时,随着集合中元素的数量和联接数量的增加,这些结果集呈指数增长(尽管Hibernate无法处理2+急切关联上的联接获取)

话虽如此,至于你的建议,你需要一个具体的(老实说,并不完全罕见)案例来解决。现在你只有一个病例,但是像这样的病例有几百个。因此,要编写规范,您需要在泛化和粒度之间划一条线


如果我站在你的立场,如果你认为这是一个绝对有用的特性,可以添加到JPA规范中,我会将它提交给JCP。另一方面,如果您在特定的实现中解决了这个(、那个和那个…),那么最终将进入所谓的供应商锁定。因此,我会额外工作一个小时,在@ManyToOne@OneToOne属性上设置延迟获取,并保持供应商自由,因此,如果出现一个比Hibernate(或您使用的任何实现)快15倍以上的新JPA实现,那么我将坚持该规范,将您的项目转移到新的JPA实现中几乎不需要任何努力。

您使用一对一来证明这一点,但多对一是更常见的关联类型。是的,在一对一关联的情况下,即时抓取可能更好。将惰性设置为默认设置更好的原因实际上更多地与这样一个事实有关,即有很多定义良好的方法可以使关联在运行时变得更为活跃(在Hibernate和JPA中),但几乎没有任何方法可以显式地使它们变为惰性。在这种情况下,一对一和多对一是如何不同的,一方如何辩护而另一方却无法辩护?我强烈认为二汉在这方面是有道理的。如果您有一个产品,但客户希望将其用于不同的JPA实现。然后,要么最终导致不一致,要么必须修改原始代码以使其与其他实现兼容。然而,你完全正确地说,不可能在运行时将一个关系变成懒惰的关系。因为经验表明,一对一的关系比我前面已经指出的多对一的关系要频繁得多。你是理想主义者;我是务实的。我更喜欢现实世界的解决方案,当然应该是这样的:“……一对一的关系比多对一的关系要少得多……”)好的,最后的评论澄清了这一点。这不是关于理想主义,而是反对你早期评论的形式…:)您完全错误地认为“Hibernate无法处理2+急切关联上的连接获取”。这是完全错误的。你可能想通过谷歌搜索“org.hibernate.loader.MultipleBagFetchException:无法同时获取多个包”来澄清,你上面的陈述引发了一个问题,即hibernate无法执行“2+急切关联上的加入获取”。错误的含义很明显,Hibernate不知何故无法获取任何类型的多个关联。然而,现实是,是的,它不能
@ManyToOne(optional = false)