In my application, a hibernate operation goes like this. The application updates a parent entity with new values from the request and deletes all the existing (previously inserted) child entities and inserts new child records.
I'm using hibernates DELETE_ORPHAN
for this, as you can see below.
When i do this, I'm getting the below exception :
org.hibernate.HibernateException: A collection with cascade="all-delete-orphan" was no longer referenced by the owning entity instance: com.childs
I saw similar threads with the problem, and I tried to appy solutions in those threads. But that didn't work
My Parent entity
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;
................
...............
}
Child entity has a combined key and has a PK entity has shown below
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 code
...................
..............
parent.getChild().clear();
Child child = new Child();
parent.setChild(child);
What could be wrong here.
Thanks in advance...
Your last snippet of Java code doesn't compile. I guess it looks like
parent.getChilds().clear(); // note: you should name it children rather than childs
parent.setChilds(someNewSetOfChildren):
Don't do the last instruction. Instead of replacing the set by another one, clear the set and add the new children to the cleared set:
parent.clearChildren();
parent.addChildren(someNewSetOfChildren);
where the methods are defined as:
public void clearChildren() {
this.children.clear();
}
public void addChildren(Collection<Child> children) {
this.children.addAll(children);
}
The setChildren method should be removed completely, or it should be replaced with the following implementation:
public void setChildren(Collection<Child> children) {
this.children.clear();
this.children.addAll(children);
}
I faced the same issue and get it solved as follows:
1- add {CascadeType.ALL}, orphanRemoval=true in all @OneToMany annotations in all entity Childs of that element.
2- Check the hashcode() and equalls() of those entities, some times they have erros
3- Don't use parent.setChilds(newChilds);
as the engine will ask for missing the reference to the childs, but use instead use
parent.getChilds().clear();
parent.getChilds().add(Child);
or
parent.getChilds().addAll(Childs);
Those steps solved my issue after 4 Hours of research
It worked for me.
Instead of setting the new child entities to my parent object, I have used addAll method to add the new child entities.
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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With