Hibernate. Remove on update child list
hibernate, jpa, orm
Solution
The update or saveOrUpdate() method does not take care the current status of the object inside the database, instead it updates all current attributes of the object. Therefore in your case, when you update the new object with its collection, it does not take care the old collection and it will update the new collection of the object. Hence, you have both the old collection and the new collection inside the database.
To overwrite the old collection by the new one, you should use the merge() method, which at first it loads the object with the same id into the persistence context, then it copies the state of the detached object to the persistent one, then it considers if the object is dirty. If so, it will persists the new object with changes.
The following code may demonstrate the above explanation:
// Initial the persistent layer
DAOLayer daoLayer = new DAOLayer();
// Persist the parent object with 1 child
Parent parent = new Parent("parent");
parent.addChild(new Child("child"));
Parent persistentParent = daoLayer.merge(parent);
// Create the new parent object with the same Id stored in DB
Parent newParent = new Parent("parent");
newParent.setId(persistentParent.getId());
newParent.addChild(new Child("child"));
// Update the new parent object
persistentParent = daoLayer.merge(newParent);
The above code results in 1 child in the database. If you change the merge() method to the saveOrUpdate() method, it results in 2 children in the database.
Problem
I have standard `@ManyToOne` association in Hibernate. When updating, I'm creating new entity (using `new` keyword) and fill it with necessary values (ID also inserted). Values comes from UI. In same way I create new collection of child objects, fill each of them by values (ID also inserted), and store collection in parent object (using setter or by `addAll()` method). So my question is: how I can remove all objects in parent collection when updating parent, and replace them by new collection. In new collection some objects are really new and some only need to be updated (they have inserted ID). I learned about `orhanRemoval`, but it can't help, because parent object must be in "managed" state (so `clear()` on child collection will not work), not in transient state as in my example..