我应该如何覆盖具有复合主键的实体中的 equals/hashCode ?

Jin*_*won 6 hibernate jpa equals hashcode composite-primary-key

我有一个带有复合主键的表,包括它自己的主键和来自其他表的 FK。

我决定不使用@IdClassnor @EmbeddedId

class SomeEntity {

    @Id
    private String someId;

    @Id
    @ManyToOne(optional = false)
    @JoinColumn(name = ...)
    private Other other

    // other mappings here
}
Run Code Online (Sandbox Code Playgroud)

Hibernate 会警告这些。

WARN 69752 ... : HHH000038: Composite-id class does not override equals(): ....Some
WARN 69752 ... : HHH000039: Composite-id class does not override hashCode(): ....Some
Run Code Online (Sandbox Code Playgroud)

我该如何(应该)实现这两种方法?

我可以(应该)只包含这两个字段吗?其他领域呢?

WARN 69752 ... : HHH000038: Composite-id class does not override equals(): ....Some
WARN 69752 ... : HHH000039: Composite-id class does not override hashCode(): ....Some
Run Code Online (Sandbox Code Playgroud)

Ste*_*rnK 1

\n

我决定不使用@IdClassnor @EmbeddedId

\n
\n

我不得不说,这个决定有两个缺点:

\n
    \n
  1. JPA规范不允许这种方法,因此它是hibernate特定的解决方案。(看这个
  2. \n
  3. 实体实例和实际标识符之间没有分隔。要查询该实体,必须将实体本身的实例提供给持久化上下文。(看这个
  4. \n
\n

想象一下,您有以下实体:

\n
@Entity\n@Table(name = "TST_FIRST_ENTITY_EHC")\npublic class FirstEntity implements Serializable \n{\n   @Id\n   @Column(name = "fst_id")\n   private Long id;\n   \n   @NaturalId\n   @Column(name = "fst_code")\n   private String code;\n   \n   @Id\n   @ManyToOne(optional = false)\n   @JoinColumn(name = "fst_sec_id")\n   private SecondEntity secondEntity;\n   \n   public FirstEntity()\n   {\n   }\n   \n   public FirstEntity(Long id, Long secId)\n   {\n      this.id = id;\n      secondEntity = new SecondEntity();\n      secondEntity.setId(secId);\n   }\n   // ...\n}\n
Run Code Online (Sandbox Code Playgroud)\n

要通过 PK 找到该实体,您应该编写如下内容:

\n
FirstEntity item = session.find(FirstEntity.class, new FirstEntity(1L, 2L));\n
Run Code Online (Sandbox Code Playgroud)\n

对于我来说,看起来很尴尬。

\n

至于您的主要问题,您可以使用标识您的实体的任何字段集。\n想象一下,对于上述实体,您有以下 DDL SQL:

\n
create table TST_FIRST_ENTITY_EHC\n(\n   fst_id bigint,\n   fst_sec_id bigint,\n   fst_code varchar(25),\n   fst_value varchar(500),\n   \n   primary key (fst_id, fst_sec_id),\n   unique(fst_code),\n   foreign key (fst_sec_id) REFERENCES TST_SECOND_ENTITY_EHC(sec_id)\n);\n
Run Code Online (Sandbox Code Playgroud)\n

您可以基于,字段或基于字段来实现实体的equals和。基于自然 ID 或业务密钥的方法更可取,因为如果您使用数据库 ID 生成,则在提交 JPA 事务之前无法知道实际的 ID 值。(参见这个)。hashCodeidsecondEntity.idcode

\n