JPA hashCode() / equals() 困境
这里已经有一些关于JPA实体的讨论,以及哪些/实现应该用于JPA实体类。它们中的大多数(如果不是全部)都依赖于Hibernate,但我想以JPA实现中立的方式讨论它们(顺便说一句,我正在使用EclipseLink)。hashCode()
equals()
所有可能的实现在以下方面都有自己的优点和缺点:
-
hashCode()
/equals()
contract conformity (immutability) for / operationsList
Set
- 是否可以检测到相同的对象(例如,来自不同会话,来自延迟加载的数据结构的动态代理)
- 实体在分离(或非持久)状态下的行为是否正确
据我所知,有三个选项:
- 不要覆盖它们;依靠和
Object.equals()
Object.hashCode()
-
hashCode()
/equals()
工作 - 无法识别相同的对象,动态代理存在问题
- 分离实体没有问题
-
- 根据主键覆盖它们
-
hashCode()
/equals()
已损坏 - 正确的标识(适用于所有托管实体)
- 分离实体的问题
-
- 根据业务 ID(非主键字段;外键呢?)覆盖它们
-
hashCode()
/equals()
已损坏 - 正确的标识(适用于所有托管实体)
- 分离实体没有问题
-
我的问题是:
- 我是否错过了一个选项和/或赞成/反对点?
- 您选择了什么选项,为什么?
更新 1:
通过“/ 被破坏”,我的意思是连续调用可能会返回不同的值,这些值(当正确实现时)在API文档的意义上没有被破坏,但是当尝试从中检索已更改的实体或其他基于哈希的实体时,这会导致问题。因此,JPA实现(至少是EclipseLink)在某些情况下将无法正常工作。hashCode()
equals()
hashCode()
Object
Map
Set
Collection
更新 2:
感谢您的回答 - 其中大多数都有非凡的质量。
不幸的是,我仍然不确定哪种方法最适合实际应用程序,或者如何为我的应用程序确定最佳方法。因此,我将保持问题的开放性,并希望有更多的讨论和/或意见。