为什么在Hibernate持久化类中覆盖hashCode()
和equals()
方法被认为是最佳做法?
答案 0 :(得分:1)
Hibernate doc:
如果你
,你必须覆盖equals()和hashCode()方法打算将持久化类的实例放在一个Set中 推荐的表示多值关联的方法)和
打算使用重新附加的分离实例
Hibernate保证持久标识的等效性(数据库行) 和Java标识仅在特定会话范围内。所以很快 当我们混合在不同会话中检索的实例时,我们必须实现 如果我们希望有有意义的语义,则equals()和hashCode() 集。
让我们考虑一下这个场景,以展示在使用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)
绝对没有理由覆盖equals
和hashCode
因为Hibernate
不依赖它们。它通过比较属性来比较实体。