使用JPA,我偶然发现了equals()
和hashcode()
的问题,特别是对于尚未保留的新创建的实体。
我在stackoverflow中找到了以下答案:
Should I write equals() methods in JPA entities?
这个答案谈到了Hibernate会话。我不使用Hibernate(但是EclipseLink),我不知道JPA提供程序的实现细节,例如这些“会话”。
我的问题是,就JPA而言,什么是Hibernate会话?或者,更具体:如果我不覆盖equals()
和hashcode()
,在哪种情况下我会遇到代表同一实体的两个对象(相同的业务密钥,如果存在)不是“相等”(这意味着equals()
返回false)?
使用相同的EntityManager实例是否足以解决这些问题(这意味着,在此上下文中,“session”和“EntityManager”可以等效使用吗?)
注意:我没有适用于所有表的业务键,因此无法应用equals()
和hashcode()
中使用业务键属性的解决方案。
答案 0 :(得分:6)
EclipseLink对equals()和hashCode()没有任何特定要求(即使在Id类上)。
在持久化上下文中,将保持标识,因此默认值为equals,hashCode将起作用。
对于分离的对象,它们将具有不同的标识,因此除非您覆盖它以使用Id或其他标准,否则equals不会返回true。这不会导致EclipseLink出现问题,但您的应用程序可能依赖于此。
一般情况下,如果您的对象在集合或映射中使用,则应正确实现equals和hashCode,但EclipseLink始终在内部使用Identity Maps和Sets,因此内部应该没有问题。
答案 1 :(得分:1)
你可能有两个相同实体的分离实例,或者一个附加的实例和一个分离的实例,因此它们不相等,因为默认的equals方法比较了物理地址。
对于没有业务密钥的实体,几乎不可能实现良好的equals方法。即使对于具有业务密钥的实体,如果此业务密钥是可变的,我们也注定失败。