我是否需要覆盖jpa实体的IdClass(组合键)中的equals()和hashCode()

时间:2017-10-05 10:51:28

标签: java hibernate jpa

如果我在Jpa实体(MyEntity)中有一个组合键,我是否需要在IdClass中添加equals()和hashCode()(在本例中为ID)?它被视为重复?或者在MyEntity“equals和hashCode()”中,我必须调用ID类的那些[返回新的MyEntity.ID(id1,id2).hashCode();在MyEntity的hashCode()中?

@Entity
@IdClass(MyEntity.ID.class)
public class MyEntity implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    private long id1;
    @Id
    private long id2;

    private String otherField;
    public static class ID implements Serializable {
        private static final long serialVersionUID = 1L;
        private long id1;
        private long id2;
        public ID() {
            super();
        }
        public ID(long id1, long id2) {
            super();
            this.id1 = id1;
            this.id2 = id2;
        }
        public long getId1() {
            return id1;
        }
        public void setId1(long id1) {
            this.id1 = id1;
        }
        public long getId2() {
            return id2;
        }
        public void setId2(long id2) {
            this.id2 = id2;
        }
        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + (int) (id1 ^ (id1 >>> 32));
            result = prime * result + (int) (id2 ^ (id2 >>> 32));
            return result;
        }
        @Override
        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }
            if (obj == null) {
                return false;
            }
            if (getClass() != obj.getClass()) {
                return false;
            }
            ID other = (ID) obj;
            if (id1 != other.id1) {
                return false;
            }
            if (id2 != other.id2) {
                return false;
            }
            return true;
        }
    }
    public MyEntity() {
        super();
    }
    public long getId1() {
        return id1;
    }
    public void setId1(long id1) {
        this.id1 = id1;
    }
    public long getId2() {
        return id2;
    }
    public void setId2(long id2) {
        this.id2 = id2;
    }
    public String getOtherField() {
        return otherField;
    }
    public void setOtherField(String otherField) {
        this.otherField = otherField;
    }
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + (int) (id1 ^ (id1 >>> 32));
        result = prime * result + (int) (id2 ^ (id2 >>> 32));
        result = prime * result + ((otherField == null) ? 0 : otherField.hashCode());
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        MyEntity other = (MyEntity) obj;
        if (id1 != other.id1) {
            return false;
        }
        if (id2 != other.id2) {
            return false;
        }
        if (otherField == null) {
            if (other.otherField != null) {
                return false;
            }
        } else if (!otherField.equals(other.otherField)) {
            return false;
        }
        return true;
    }
}

2 个答案:

答案 0 :(得分:2)

请查看此问题JPA/Hibernate “Composite-id class does not override equals()”

以下是有关equals() and hashCode()

的文档中的一些内容
  

我们建议您使用商家密钥实施equals()hashCode()   平等即可。业务键平等意味着equals()方法   仅比较形成业务键的属性,即键   将识别我们在现实世界中的实例(自然候选人   键)

equals / hashCode的问题并不简单,也没有一个通用的解决方案。

  

尽管使用natural-id最适合equals和hashCode,但有时也是如此   您只有提供唯一约束的实体标识符。

     

可以使用实体标识符进行相等性检查,但它可以   需要一个解决方法:

     

你需要为hashCode提供一个常量值,以便散列   在刷新实体之前和之后,代码值不会改变。

     

您只需要比较实体标识符的相等性   非瞬态实体。

也是一篇好文章EqualsandHashCode

答案 1 :(得分:2)

1

  

我是否需要在IdClass中添加equals()和hashCode()(在本例中为ID)?

是的,你确实需要它。这是the documentation

  

复合主键类具有以下特征:

     

...

     
      
  • 它定义了equals和hashCode方法。这些方法的值相等的语义必须与键映射到的数据库类型的数据库相等一致。
  •   
     

...

2

  

或在MyEntity" equals和hashCode()"中,我必须调用ID类的那些[返回新的MyEntity.ID(id1,id2).hashCode();在MyEntity的hashCode()中?

我不确定你的意思,但你不需要构建新的ID类实例。只需按照等于&来自the documentation的hasCode合约规则。 (在IDE中自动生成equals和hasCode也可以正常工作)。