考虑这种情况:
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:非空属性引用 null 或 transient
因为属性父为“Optional=false”
所以我必须替换parent.setChildren(childList);
并在parentService()中执行如下循环:
for(Child c: childList){
c.setFather(parent.getId());
parent.getChildrent().add(c);
}
这是正确的吗?有没有更好的方法可以不用再次循环childList?
最佳答案
使用 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()
的可见性可以限制以避免错误调用。
同样,您没有级联并且没有将子项保留在与父项相同的事务中,这看起来很奇怪。
关于hibernate - JPA Hibernate 一对多批量插入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5427456/