我有一個關於Hibernate 3.6.7和JPA 2.0的問題。Hibernate插入重複項到@OneToMany集合
考慮下面的實體(一些getter和setter是爲了簡潔省略):
@Entity
public class Parent {
@Id
@GeneratedValue
private int id;
@OneToMany(mappedBy="parent")
private List<Child> children = new LinkedList<Child>();
@Override
public boolean equals(Object obj) {
return id == ((Parent)obj).id;
}
@Override
public int hashCode() {
return id;
}
}
@Entity
public class Child {
@Id
@GeneratedValue
private int id;
@ManyToOne
private Parent parent;
public void setParent(Parent parent) {
this.parent = parent;
}
@Override
public boolean equals(Object obj) {
return id == ((Child)obj).id;
}
@Override
public int hashCode() {
return id;
}
}
現在考慮這段代碼:
// persist parent entity in a transaction
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
Parent parent = new Parent();
em.persist(parent);
int id = parent.getId();
em.getTransaction().commit();
em.close();
// relate and persist child entity in a new transaction
em = emf.createEntityManager();
em.getTransaction().begin();
parent = em.find(Parent.class, id);
// *: parent.getChildren().size();
Child child = new Child();
child.setParent(parent);
parent.getChildren().add(child);
em.persist(child);
System.out.println(parent.getChildren()); // -> [[email protected], [email protected]]
em.getTransaction().commit();
em.close();
子實體被錯誤地插入兩次到列表的父實體的子女。
當執行下列操作之一,代碼工作正常(無重複的條目列表):
- 刪除
mappedBy
屬性在父實體 - 執行兒童名單上的一些讀操作(例如,標註爲
*
的取消註釋行)
這顯然是一個非常奇怪的行爲。另外,使用EclipseLink作爲持久性提供者時,代碼的工作方式與預期的一樣(不重複)。
這是一個Hibernate的bug還是我錯過了什麼?
謝謝
之前,您可以加入該方法的setParent和的平等/ hashCode方法的代碼? –
我剛剛添加了您要求的方法。但是,我不認爲這個問題與equals/hashCode相關。 – user1014562
您的equals方法不尊重Object.equals的合約。此外,hashCode在ID生成並分配給實體時發生變化。如果在刪除hashCode和equals時該錯誤消失,我不會感到驚訝。 BTW。 Hibernate建議不要使用ID來實現equals和hashCode。 –