2011-03-25 137 views
1

求索這樣的場景:JPA Hibernate的一對多批量插入

class Parent { 
    private Integer id; 
    private String name; 
    @oneToMany(mappedBy="father") 
    private List<Child> children; 
    ... ... 
    } 

    class Child { 
    private Integer id; 
    private String name; 
    @ManyToOne (optional="false") 
    @JoinColumn(name="id") 
    private Parent father; 
    ........ 
} 


Class MyParentService{ 

    public Parent parentService(List<Child> childList){ 
     em.getTransaction.begin(); 
     Parent parent = new Parent(); 
     parent.setChildren(childList); 
     em.persist(parent); 
     em.getTransaction.commit(); 
    } 
} 

因爲屬性的父親是我拿的org.hibernate.PropertyValueException: not-null property references a null or transient

了異常「可選=假」

所以我必須替換parent.setChildren(childList);並在parentService()中執行如下循環:

for(Child c: childList){ 
c.setFather(parent.getId()); 
parent.getChildrent().add(c); 
} 

這是正確的嗎?有沒有更好的方式做不再循環childList?

回答

3

在使用Hibernate時,您有責任保持雙向關係雙方的一致狀態。此外,當持續關係時,Hibernate會查看擁有方(沒有mappedBy的那一方),所以即使沒有optional=false,您的代碼也不會正確。

您可以使用下面的方法,以確保consistensy:

class Parent { 
    ... 
    public void addChild(Child c) { 
     children.add(c); 
     c.setParent(this); 
    } 
} 

public Parent parentService(List<Child> childList) { 
    ... 
    for (Child c: childList) { 
     parent.addChild(c); 
    } 
    ... 
} 

setChildren()這種情況下,知名度可以被限制,以避免錯誤的電話。

另外,您看起來很奇怪,您沒有級聯,也不會將孩子留在與父母同一交易中。

+0

謝謝!我在兩邊添加了cascade = {CascadeType.ALL}。我不明白你的意思是什麼「看起來很奇怪,你沒有堅持讓孩子與父母進行同樣的交易。」是不是當我堅持父母會自動堅持他和他的收藏的所有元素?? (兒童) – Kossel 2011-03-25 16:25:48

+0

只有在您配置級聯時,集合的元素纔會自動保持,所以沒有'cascade'看起來很奇怪。 – axtavt 2011-03-25 16:51:53

0

我認爲這是件好事 - 例如,在單元測試中,您可能不會使用自動設置「父親」的hibernate,但代碼仍然可以工作。

+0

Hibernate沒有自動設置「father」。 – axtavt 2011-03-25 09:02:45