Overview
If you have come across the error a collection with cascade=”all-delete-orphan” was no longer referenced by the owning entity instance, chances are :
- You have two entities, a Parent and its Child.
- You are deleting (Or removing some old and adding new) Child records and updating the Parent.
In this specific case, the error message suggests that you have a collection of child objects in an entity (the “owned” entity), and that this collection is set up to be deleted when the owning entity is deleted (“cascade=all-delete-orphan”). Hence the error message.
Going through this article will help you resolve this error and provide you insight on the details of the solution
The Parent and Child entity classes, which are being used in your application code would look as below.
Parent.java
package com; @Entity class Parent { @OneToMany(mappedBy="parent", cascade={CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH}, orphanRemoval=true) private List children; public List getChildren(){ return children; } public void setChildren(List list){ children = list }
Child.java
package com; @Entity class Child { @ManyToOne @JoinColumn(name = "parentid") Parent parent; }
The logic or the piece of code which is generating the error would be somewhat like :
//fetch parent record from database Parent parent = findById(parentId); // create new child Child child = new Child(); //create new children list List children = new ArrayList(); //add child to the list of children children.add(child); //clear existing children list so that they are removed from database parent.getChildren.clear(); //set the new children list created above parent.setChildren(children); //update parent update(parent);
When the above code executes, you get an error like:
org.hibernate.HibernateException: A collection with cascade=”all-delete-orphan” was no longer referenced by the owning entity instance: com.children
Solution
Slightly change the method of associating the list of children after clearing it from the parent. That is, replace the following lines of code
//clear existing children list so that they are removed from database parent.getChildren.clear(); //set the new children list created above parent.setChildren(children);
to
//clear existing children list so that they are removed from database parent.getChildren.clear(); //add the new children list created above to the existing list parent.getChildren.addAll(children);
Reason
In the first approach, you clear the existing collection of children associated with the parent entity, create a new collection(ArrayList) and assign it to the child list of the parent.
The previous collection is now not associated with any entity but it remains in the session. The error A collection with cascade=“all-delete-orphan” was no longer referenced by the owning entity instance
says it all.
In the second approach, you clear the existing collection of children associated with the parent entity, create a new collection(ArrayList) but instead of assigning the new collection to child list, add the new collection to this list.
Now, in this case, the collection of child entities still remains associated with an entity(the parent entity).
Therefore, when you try to update, Hibernate(or JPA) finds no problem and updates both the parent and its children successfully.
Hope this post helped you to resolve the error !!!