JPA hashCode()/equals() 困境 [英] The JPA hashCode() / equals() dilemma

查看:33
本文介绍了JPA hashCode()/equals() 困境的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

已经有一些 讨论 这里关于 JPA 实体和哪些 hashCode()/equals() 实现应该用于 JPA 实体类.它们中的大多数(如果不是全部)都依赖于 Hibernate,但我想以 JPA 实现中立的方式讨论它们(顺便说一下,我正在使用 EclipseLink).

There have been some discussions here about JPA entities and which hashCode()/equals() implementation should be used for JPA entity classes. Most (if not all) of them depend on Hibernate, but I'd like to discuss them JPA-implementation-neutrally (I am using EclipseLink, by the way).

所有可能的实现在以下方面都有自己的优点缺点:

All possible implementations are having their own advantages and disadvantages regarding:

  • hashCode()/equals() List 契约一致性(不变性)代码>/<代码>设置操作
  • 是否可以检测相同的对象(例如来自不同会话、来自延迟加载的数据结构的动态代理)
  • 实体在分离(或非持久化)状态下的行为是否正确
  • hashCode()/equals() contract conformity (immutability) for List/Set operations
  • Whether identical objects (e.g. from different sessions, dynamic proxies from lazily-loaded data structures) can be detected
  • Whether entities behave correctly in detached (or non-persisted) state

据我所知,有三个选项:

  1. 不要覆盖它们;依赖于 Object.equals()Object.hashCode()
    • hashCode()/equals() 工作
    • 无法识别相同的对象,动态代理有问题
    • 分离实体没有问题
  • hashCode()/equals() 已损坏
  • 正确的身份(适用于所有托管实体)
  • 分离实体的问题
  • hashCode()/equals() 已损坏
  • 正确的身份(适用于所有托管实体)
  • 分离实体没有问题

我的问题是:

  1. 我是否错过了一个选项和/或利弊?
  2. 您选择了什么选项?为什么?



更新 1:

通过hashCode()/equals() 被破坏",我的意思是连续的 hashCode() 调用可能返回不同的值,从 Object API 文档的意义上来说,它(如果正确实现)没有被破坏,但是在尝试从 Map 检索更改的实体时会导致问题Set 或其他基于散列的 Collection.因此,在某些情况下,JPA 实现(至少 EclipseLink)将无法正常工作.

By "hashCode()/equals() are broken", I mean that successive hashCode() invocations may return differing values, which is (when correctly implemented) not broken in the sense of the Object API documentation, but which causes problems when trying to retrieve a changed entity from a Map, Set or other hash-based Collection. Consequently, JPA implementations (at least EclipseLink) will not work correctly in some cases.

更新 2:

感谢您的回答——他们中的大多数都具有非凡的品质.
不幸的是,我仍然不确定哪种方法最适合实际应用程序,或者如何确定我的应用程序的最佳方法.所以,我会保持这个问题的开放性,并希望有更多的讨论和/或意见.

Thank you for your answers -- most of them have remarkable quality.
Unfortunately, I am still unsure which approach will be the best for a real-life application, or how to determine the best approach for my application. So, I'll keep the question open and hope for some more discussions and/or opinions.

推荐答案

阅读这篇关于这个主题的非常好的文章:不要让 Hibernate 窃取您的身份.

Read this very nice article on the subject: Don't Let Hibernate Steal Your Identity.

文章的结论是这样的:

对象标识在以下情况下很难正确实现对象被持久化到数据库中.然而,问题出在完全从允许对象在没有 id 的情况下存在保存.我们可以通过承担责任来解决这些问题从对象关系映射框架分配对象 ID比如休眠.相反,对象 ID 可以在对象被实例化.这使得对象标识变得简单和无错误,并减少了领域模型所需的代码量.

Object identity is deceptively hard to implement correctly when objects are persisted to a database. However, the problems stem entirely from allowing objects to exist without an id before they are saved. We can solve these problems by taking the responsibility of assigning object IDs away from object-relational mapping frameworks such as Hibernate. Instead, object IDs can be assigned as soon as the object is instantiated. This makes object identity simple and error-free, and reduces the amount of code needed in the domain model.

这篇关于JPA hashCode()/equals() 困境的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆