根据我的理解@OneToOne
和@ManyToOne
JPA注释执行eager
抓取。我希望这些在我的应用程序中延迟加载,或者至少提示它(这是hibernate默认的)。我已经开始添加注释fetch = FetchType.LAZY
例如
@ManyToOne(optional = false, fetch = FetchType.LAZY)
而不是
@ManyToOne(optional = false)
这既乏味又容易出错。有没有办法在应用程序级别执行此操作?在persistence.xml中也许?
答案 0 :(得分:19)
到目前为止,我选择让Hibernate遵循JPA规范,通过注释进行映射只是因为我没有收到任何使其可配置的功能请求,这是令人惊讶的TBH。正如您所指出的,因为Hibernate 3.0所需的是使用hbm.xml
映射文件时的默认设置。
允许通过配置不会违反规范,如另一个答案所示。
故事很长,今天不可能。如果您希望看到可配置,请创建功能请求。
答案 1 :(得分:6)
JPA Spec假设通常大多数应用程序默认需要单例关系,而默认情况下多值关系是惰性的。至少根据我自己的经验,这通常是理想的架构。这是有道理的,因为单例关系在JPA层和DB层中不需要显着的额外性能来在外键上创建单例连接。但是,与此相反,多值属性会产生N + 1问题或大型笛卡尔结果集,当使用连接提取时,随着集合中元素的数量和连接数的增加,指数会膨胀(尽管Hibernate特别无法处理连接提取2 +渴望的协会)。
话虽如此,至于你的建议,你需要一个特定的(事实并非完全不常见的)案例。现在你有一个案例,但因为有数百个案例。因此,要编写规范,您需要在泛化和粒度之间划一条线。
如果我认为这是一个非常有用的功能,可以添加到JPA规范中,我会将其提交给JCP。另一方面,如果你在特定的实现中得到了这个(那个和那个...)那么你最终会进入所谓的vendor-lockin。因此,我会花费额外的时间在@ManyToOne @OneToOne属性上设置延迟获取并保持供应商免费,因此如果说新的JPA实现比Hibernate(或者任何实现的话)快了15倍,那么坚持使用规范使用),将您的项目移动到新的JPA实现几乎没有任何努力。
答案 2 :(得分:3)
没办法。在JPA规范中没有改变全局提取策略。 JPA提供1-1 / N-1关联EAGER提取,而对于1-N / M-N则为LAZY。所有JPA实现都应遵循规范要求。我认为,最好是应用程序开发人员不能在全局范围内更改此默认设置,因为这些是几乎在大多数情况下的最佳实践,除非您在所有实体之间只有一种类型的关联,例如1-1。想一想,你可以在一个应用程序中将它设置为“EAGER”,它包含一个真正丰富的实体模型,该模型具有复杂的关系和数据库中的数百万个数据。手动覆盖每个关联的提取策略允许开发人员承担下一步将发生的事情的责任。它不是容易出错的,而是一个强大的功能。
答案 3 :(得分:1)
根据我的理解@oneToOne和@ManyToOne JPA注释做了 渴望fectch。
JPA保证对单值关系的加载加载,如果没有通过注释或持久性XML声明。对于集合值关系,它默认为延迟加载,但延迟加载(仅)提示支持JPA的持久性提供程序,因此您不能依赖它,并且必须检查特定的提供程序(例如Hibernate,OpenJPA)。请参阅this link作为参考,以获取更多信息。