在我的应用程序中,hibernate操作是这样的。 应用程序使用请求中的新值更新父实体,并删除所有现有(先前插入的)子实体并插入新的子记录。
我正在使用hibernates DELETE_ORPHAN
,如下所示。
当我这样做时,我得到以下例外:
org.hibernate.HibernateException:一个集合 所有者不再引用cascade =“all-delete-orphan” 实体实例: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);
这里可能有什么不妥。
提前谢谢......
答案 0 :(得分:52)
您的最后一段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 :(得分:9)
它对我有用。
我没有将新的子实体设置为我的父对象,而是使用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;
}
答案 2 :(得分:7)
我面临同样的问题并按如下方式解决:
1-在该元素的所有实体子项中的所有 @OneToMany 注释中添加 {CascadeType.ALL},orphanRemoval = true 。
2-检查这些实体的哈希码()和 equalls(),有时它们有错误
3-不要使用parent.setChilds(newChilds);
,因为引擎会要求错过对孩子的引用,但请改用
parent.getChilds().clear();
parent.getChilds().add(Child);
或
parent.getChilds().addAll(Childs);
这些步骤在经过4个小时的研究后解决了我的问题
答案 3 :(得分:4)
而不是setChilds
使用addAll
,
从此,
parent.getChilds().clear();
parent.setChilds(newChilds);
到
parent.getChilds().clear();
parent.getChilds().addAll(newChilds);
答案 4 :(得分:0)
它可以改变!
@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "user_id")
private List<Role> roles;