为什么要在hibernate持久化类中覆盖hashCode和equals方法?

时间:2016-08-23 11:50:14

标签: java hibernate

为什么在Hibernate持久化类中覆盖hashCode()equals()方法被认为是最佳做法?

2 个答案:

答案 0 :(得分:1)

Hibernate doc:

  

如果你

,你必须覆盖equals()和hashCode()方法      

打算将持久化类的实例放在一个Set中   推荐的表示多值关联的方法)和

     

打算使用重新附加的分离实例

     

Hibernate保证持久标识的等效性(数据库行)   和Java标识仅在特定会话范围内。所以很快   当我们混合在不同会话中检索的实例时,我们必须实现   如果我们希望有有意义的语义,则equals()和hashCode()   集。

请参阅此链接https://docs.jboss.org/hibernate/stable/core.old/reference/en/html/persistent-classes-equalshashcode.html

让我们考虑一下这个场景,以展示在使用equals和hashcode的默认实现时会出现的一些问题:

@Entity Parent{
        @Id
        @GeneratedValue
        Long id;

        @OneToMany(mappedBy = "parent",
         cascade = CascadeType.ALL, orphanRemoval = true)
        @JoinColumn(name="PARENT_ID")
        Set<Child> childrens = new HashSet<Child>();
        //get+set
        }

@Entity Child{
        @Id
        @GeneratedValue
        Long id;
        }
    test(){
          Parent p1 = new Parent();
          Child c1 = new Child();
          entityManager.persist(p1);
          entityManager.persist(c1);
          p1.getChilds.add(c1);
          entityManager.merge(p);
          //!!:using another instance of entitymanager just to simulate the case of detached entities.
          Parent p2 =entityManager1.find(p1.getId(),Parent.class);
          child c2 =entityManager1.find(c1.getId(),Child.class);
          boolean contains=p1.getChilds().contains(c2); // problem1: contains==false
          //Then if we add c2 to the childs set we will have 
          //a duplication inside the Set
          p2.getChilds.add(c2);//problem2:childs contains c1 and c2
          boolean remove=p2.getChilds.remove(c2);//problem3:remove==false
          entityManager1.merge(p2);//problem4: hibernate will deal with c2
          //like a new entity then an insert operation is 
          //triggered on c2 (an exception=> violation of unique id)
        }

答案 1 :(得分:0)

绝对没有理由覆盖equalshashCode因为Hibernate不依赖它们。它通过比较属性来比较实体。