JPA @ManyToOne 用于休眠

Posted

技术标签:

【中文标题】JPA @ManyToOne 用于休眠【英文标题】:JPA @ManyToOne for hibernate 【发布时间】:2016-10-08 22:43:33 【问题描述】: 老派休眠 - ManyToOne 很懒 JPA - ManyToOne 非常渴望

在 OneToMany 中都是懒惰的感谢上帝。

休眠中是否有设置可以覆盖这个非常糟糕的设置?有太多人继续添加 ManyToOnes 而没有将它们设置为惰性(即他们忘记添加 FetchType.LAZY),导致大量不必要的连接,在某些情况下导致 6 个不需要的表被连接。

除非开发人员转移到 JQL 以急切地获取某些东西,否则一切都应该是懒惰的。然后它更加一致,并帮助开发人员在每次添加 ManyToOne 注释时都不会犯这些错误

或者,在 hibernate 5.2 中,仍然可以使用 hibernate 注释吗?但是我需要以某种方式从类路径中删除 JPA 注释,因为我担心它们会不小心回到我们身边(我们都是人类)。

我发现这篇很棒的文章比我能更好地解释一切都应该如何变得懒惰https://vladmihalcea.com/eager-fetching-is-a-code-smell/

谢谢, 院长

【问题讨论】:

【参考方案1】:

Hibernate(或任何其他框架)不可能将注释属性的默认值与设置的相同值区分开来。

我的意思是在运行时@ManyToOne@ManyToOne(fetch = FetchType.EAGER) 完全相同。

但由于您无法更改运行时行为,您至少可以调整编译时间:您可以添加一个 Checkstyle 规则(或任何类似规则),强制您的同事始终设置 fetch显式键入。

Checkstyle 示例:

<module name="RegexpSinglelineJava">
  <property name="format" value="@(One|Many)ToOne(?!\([^)]*fetch)"/>
  <property name="message" value="Please declare the fetch type (and use EAGER sparingly)"/>
  <property name="ignoreComments" value="true"/>
</module>

如果在 @OneToOne@ManyToOne 之后未定义提取,则会添加编译时警告。

【讨论】:

【参考方案2】:

无法全局覆盖默认值,但您可以尝试获取源代码,更改并编译它。

https://github.com/eclipse/javax.persistence/blob/master/src/javax/persistence/ManyToOne.java

第 111 行。

FetchType fetch() default EAGER;

【讨论】:

至少对于 JEE 应用程序服务器(包含其他应用程序)来说,这是您无法做到的。所以我会谨慎使用 always 这个词。

以上是关于JPA @ManyToOne 用于休眠的主要内容,如果未能解决你的问题,请参考以下文章

如何通过级联级联@ManyToOne 双向关系?

kotlin 的 JPA:lazy 和 @Transient 不适用于休眠

休眠 OneToMany 和 ManyToOne?

使用 FetchType.LAZY 休眠 ManyToOne 不会延迟获取

无法使用 OneToMany 和 ManyToOne 关系在休眠中创建表(也无法创建外键)

JPA、OneToMany 和 ManyToOne