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?
答案 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,但代码仍然有用。