JPA Hibernate一对多批量插入

时间:2011-03-25 01:04:06

标签: hibernate jpa

考虑到这种情况:

    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

的例外情况

因为属性father是“optional = false”

所以我必须替换parent.setChildren(childList);并在parentService()中执行这样的循环:

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

这是对的吗?有没有更好的方法可以不再循环childList?

2 个答案:

答案 0 :(得分:3)

使用Hibernate时,您有责任保持双向关系双方的一致状态。此外,当持久化关系时,Hibernate会查看拥有方(没有mappedBy的那一方),因此即使没有optional=false,您的代码也不正确。

您可以使用以下方法来确保一致:

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()的可见性以避免错误的呼叫。

Aslo,看起来很奇怪,你没有级联,也没有将孩子留在与父母相同的交易中。

答案 1 :(得分:0)

我认为这样做很好 - 例如在单元测试中,您可能不会使用自动设置“父”的hibernate,但代码仍然有用。