【问题标题】:equals() and hashcode() for JPA entities using EclipseLink使用 EclipseLink 的 JPA 实体的 equals() 和 hashcode()
【发布时间】:2011-09-25 22:58:05
【问题描述】:

使用 JPA,我偶然发现了 equals()hashcode() 的问题,尤其是对于尚未持久化的新创建实体。

我在stackoverflow中找到了以下答案:

Should I write equals() methods in JPA entities?

这个答案谈到了休眠会话。我不使用 Hibernate(但使用 EclipseLink),而且我不了解 JPA 提供程序的实现细节,例如这些“会话”。

我的问题是,就 JPA 而言,Hibernate 会话是什么?或者,更具体地说:如果我不覆盖 equals()hashcode(),在这种情况下,我会遇到表示同一实体的两个对象(相同的业务密钥,如果存在)不“相等”的问题(这意味着equals() 返回 false)?

使用相同的 EntityManager 实例是否足以避免这些问题(这意味着,“session”和“EntityManager”可以在这种情况下等效使用吗?)

注意:我没有对所有表都可用的业务密钥,因此无法应用在equals()hashcode() 中使用业务密钥属性的解决方案。

【问题讨论】:

    标签: java jpa equals


    【解决方案1】:

    EclipseLink 对 equals() 和 hashCode() 没有任何特定要求(即使在 Id 类上也是如此)。

    在持久化上下文中,身份被维护,所以默认的 equals 和 hashCode 会起作用。

    对于分离的对象,它们将具有不同的标识,因此 equals 不会返回 true,除非您覆盖它以使用 Id 或其他一些条件。这不会导致 EclipseLink 出现问题,但您的应用程序可能对此有依赖关系。

    如果您的对象在 Sets 或 Maps 中使用,通常应该正确实现 equals 和 hashCode,但 EclipseLink 始终在内部使用 Identity Maps 和 Sets,因此内部应该没有问题。

    【讨论】:

    • 顺便说一句,至于这是一个权威的答案:see James' profile!
    • @James:EclipseLink 总是使用身份集(仍然)是真的吗?我们有一个特别糟糕的 hashCode 实现,并且在删除时遇到了巨大的性能问题。查看 UnitOfWorkImpl 的代码,我看到删除依赖项都使用 vanilla HashMap/HashSets 进行跟踪。这是一个错误还是设计使然?无论哪种方式,它似乎都与 EclipseLink 不需要这些方法的任何东西的想法相矛盾。
    【解决方案2】:

    您可以拥有同一实体的两个分离实例,或者一个附加实例和一个分离实例,因此它们不相等,因为默认的 equals 方法比较物理地址。

    几乎不可能为没有业务密钥的实体实现良好的 equals 方法。甚至对于具有业务密钥的实体,如果此业务密钥是可变的,我们就完蛋了。

    【讨论】:

      猜你喜欢
      • 2011-07-08
      • 1970-01-01
      • 2010-12-10
      • 2014-09-04
      • 2011-05-22
      • 1970-01-01
      • 2011-11-12
      • 2011-03-09
      • 1970-01-01
      相关资源
      最近更新 更多