【问题标题】:JPA/Hibernate "Composite-id class does not override equals()"JPA/Hibernate“复合 id 类不覆盖 equals()”
【发布时间】:2014-03-25 21:18:03
【问题描述】:

我正在使用 JPA 并收到以下警告。我已经对此进行了研究,并了解了为什么我需要覆盖它以及 Hibernate 如何使用这些方法。不过我还有一个问题:

例外:

Composite-id 类不覆盖 equals()

问题:

为什么 Hibernate 只关心没有复合 ID 的类?如果只有一个存在,默认情况下会在 @Id 字段上进行比较,还是这里发生了更复杂的事情?

【问题讨论】:

    标签: java jpa


    【解决方案1】:

    因为当实体没有复合 ID 时,它们只有一个,是一种基本支持的类型(整数、长整型、字符串等),并且这些类已经有一个明确定义的 equals() (和hashCode())方法。

    【讨论】:

    • 那么,我需要创建一个主键类,还是只在类中有 2 个 @Id 标量字段并在那里覆盖等于?
    • 您应该避免使用复合键。这才是你真正应该做的。如果你真的不能因为你的目标是一个不能改变的现有模式,那么你应该定义一个 PK 类,是的。
    • 很酷,谢谢,我会接受的。但是最后一个问题......在正常的多对多非规范化场景中,您如何避免它们,您需要一个只包含 2 个外键的表?您可以让第三个自动生成的键作为主键,但该键在不同的数据中心最终会有所不同,这很麻烦,并且会使调试变得非常复杂。
    • 如果您在两个表之间有一个多对多关联,使用连接表,那么您应该在实体之间有一个多对多关联。无需映射连接表。该协会处理它。阅读文档。
    • 哎呀,你是对的。我已经在使用连接表,我只是在开始工作之前创建了每个数据库实体。事实证明,报告错误的实体甚至没有在 Java 代码中的任何地方使用。谢谢大佬。
    【解决方案2】:

    在使用复合键时使用 JPA,您应该使用 IdClassEmbeddedId 使用它们中的任何一个,您需要创建一个自己的类作为复合键,以便能够使用它来比较对象EntityManager 中的多个操作所需的复合键,键类必须覆盖 equalshashCode

    取自规格:

    复合主键必须对应于单个持久字段或属性,或者对应于如下所述的一组此类字段或属性。必须定义一个主键类来表示一个复合主键。当数据库键由多个列组成时,通常会在从遗留数据库映射时出现复合主键。 EmbeddedIdIdClass 注解用于表示复合主键。

    并且在使用复合主键时必须遵循。

    1. 主键类必须是公共的,并且必须有一个公共的无参数构造函数。
    2. 主键类必须是可序列化的。
    3. 主键类必须定义equalshashCode 方法。这些方法的值相等语义必须与键映射到的数据库类型的数据库相等性一致。

    【讨论】:

    • 那么,我不能有一个包含多个 @Id 列的类,而只是覆盖那里的等于?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-07-08
    • 2017-12-19
    • 2020-11-15
    • 1970-01-01
    • 2013-07-05
    • 2016-07-12
    • 2013-08-20
    相关资源
    最近更新 更多