2012-06-25 72 views
0

這裏是我的代碼JPA - 無效的重複插入

@Entity 
class Parent extends Person { 
    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true, mappedBy = "father") 
    private List<Child> children; 

    // ... 

    public void addChild(Child c) { 
     children.add(c); 
    } 

} 

@Entity 
class Child extends Person { 
    @ManyToOne(cascade=CascadeType.ALL) 
    @JoinColumn(name = "id") 
    private Parent father; 

    public Child() { 
     this(NoParent.getInstance());// 
    } 

    public Child(Parent p) { 
     super(); 
     setParent(p); 
    } 

    // ... 
} 

@MappedSuperclass 
class Person { 
    @Id 
    private Integer id; 
    private String name; 
} 

class MyParentService { 

    public void addChild(String name, Parent parent) { 
     Child c = new Child(parent); 
     c.setName(name); 
     parent.addChild(c); 

     em.getTransaction.begin(); 
     em.merge(parent); 
     em.getTransaction.commit();// Here two children with same name but different ids are created ... 
    } 
}  

我每次運行它,兩個孩子被添加到數據庫中,而我只是想要一個!
我在做什麼錯?

的Java 6
JPA 2
的Hibernate 3.6.8.GA

+0

您可以添加接收父級的子構造函數以及父級上的addChild方法的代碼嗎? – jpkrohling

+0

@partenon我用構造函數和方法代碼更新了我的代碼。 – Stephan

+0

你可以添加Child的setParent代碼嗎?如果這包含一個對Parent的addChild的調用,那麼一個新的Child將顯然被添加兩次。 – Gandalf

回答

1

我讀了Hibernate文檔,這真的很讓人困惑,並沒有多大幫助。

請注意,我發現ObjectDB最近遇到並修復了the exact same bug。 (Hibernate的傢伙你爲什麼等了這麼久?)

然而,這裏的解決方案,我想出了:

第1步:
創建一個全新的子(即分離狀態)並調用setParent方法來鏈接到它的父代。

第2步:
堅持這個孩子。

第3步:
進行更改孩子,因爲你需要,後來合併。

該解決方案是相當不優雅,但它的工作原理! 接下來,您將獲取您的父對象,它會將之前的子對象(ren)手動鏈接到它。

2

你任何機會堅持孩子家長後?另外,最好的做法是隻管理關係的所有方(僅在一個方法中使用parent.addChild和child.setParent)來管理對象的鏈接,但這對於您的情況似乎並不重要,因爲對象在「合併」發生時正確鏈接。如果這些都不起作用,那麼你可能會碰到這個:https://hibernate.onjira.com/browse/HHH-5855

+0

我創建一個新鮮的小孩('new'運算符),將它添加到它的父項。儘管如此,我看了一下bug,沒有任何解決方法似乎適用於我。我沒有得到任何兒童記錄,一個孩子記錄沒有更新或更糟兩個孩子的記錄:更新記錄之前和之後.. – Stephan