在我的应用程序中,hibernate操作如下。应用程序使用请求中的新值更新父实体,删除所有现有(以前插入的)子实体并插入新的子记录。
我使用hibernates DELETE_ORPHAN
,如下所示。
当我这样做时,我会得到以下异常:
org.hubinate.hibernate异常:具有cascade="所有删除孤立项"不再被拥有者引用实体实例:com.childs
我在这个问题上看到了类似的线程,我试图在这些线程中应用解决方案。但不起作用
我的母公司
public class Parent implements Serializable {
@Column(name = "PARENT_ID")
@Basic(fetch = FetchType.EAGER)
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seq")
@SequenceGenerator(name = "seq", sequenceName = "seq")
private Integer parentId; //primary key of parent
.......
........
//mapping to child entity
@OneToMany(mappedBy = "parent", cascade = { CascadeType.ALL }, fetch = FetchType.LAZY)
@Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
private Set<Child> childs;
................
...............
}
子实体有一个组合密钥,并有一个PK实体,如所示
public class ChildPK implements Serializable {
/** The Constant serialVersionUID. */
private static final long serialVersionUID = -447592368963477750L;
/** . */
@ManyToOne(cascade = { CascadeType.ALL }, fetch = FetchType.LAZY)
@JoinColumns( { @JoinColumn(name = "PARENT_ID", referencedColumnName = "PARENT_ID") })
@Id
private Parent parent;
/**. */
@Column(name = "CHILD_ID")
@Basic(fetch = FetchType.EAGER)
@Id
@GenericGenerator(name="child_seq", strategy="com.DB2Dialect")
@GeneratedValue(generator="child_seq")
private Integer childId;
}
child entity goes like this:
public class Child implements Serializable {
/** The Constant serialVersionUID. */
private static final long serialVersionUID = 185670997643552301L;
/** The pol cntct id. */
@Column(name = "CHILD_ID")
@Basic(fetch = FetchType.EAGER)
@Id
private Integer childId;
@ManyToOne(cascade = { CascadeType.ALL }, fetch = FetchType.LAZY)
@JoinColumns( { @JoinColumn(name = "PARENT_ID", referencedColumnName = "PARENT_ID") })
@Id
private Parent parent;
}
Java代码
...................
..............
parent.getChild().clear();
Child child = new Child();
parent.setChild(child);
这里可能出了什么问题
提前感谢。。。
您的最后一段Java代码没有编译。我想它看起来像
parent.getChilds().clear(); // note: you should name it children rather than childs
parent.setChilds(someNewSetOfChildren):
不要执行最后一条指令。与其用另一个集合替换该集合,不如清除该集合并将新的子集合添加到已清除的集合中:
parent.clearChildren();
parent.addChildren(someNewSetOfChildren);
其中方法定义为:
public void clearChildren() {
this.children.clear();
}
public void addChildren(Collection<Child> children) {
this.children.addAll(children);
}
setChildren方法应该完全删除,或者用以下实现替换:
public void setChildren(Collection<Child> children) {
this.children.clear();
this.children.addAll(children);
}
我遇到了同样的问题,并按如下方式解决了它:
1-在该元素的所有实体Childs的所有@OneToMany注释中添加{CascadeType.ALL},orphanRemoval=true。
2-检查这些实体的hashcode()和equals()有时它们会错误
3-不要使用parent.setChilds(newChilds);
,因为引擎会要求缺少对子级的引用,而是使用
parent.getChilds().clear();
parent.getChilds().add(Child);
或
parent.getChilds().addAll(Childs);
经过4小时的研究,这些步骤解决了我的问题。
它对我有效。
- 清除了我的所有子实体
-
我没有将新的子实体设置为父对象,而是使用addAll方法添加新的子对象。
parent.getChildren().clear(); parent.getChildren().addAll(newChildrenList); @OneToMany(mappedBy = "parent", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true) public Set<Children> getChildren() { return this.children; }
使用addAll
,而不是setChilds
由此,
parent.getChilds().clear();
parent.setChilds(newChilds);
至
parent.getChilds().clear();
parent.getChilds().addAll(newChilds);
它改变了工作原理!
@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "user_id")
private List<Role> roles;