Hibernate mapping: delete-orphan cascade

1.3k views Asked by At

Question about hibernate and delete-orphan cascade. Suppose I have some Parent class with collection of Child inside it. In hibernate mapping for Parent class for one-to-many relation I set cascade all-delete-orphan. Suppose that all the rest is configured correctly.

So, I load Parent P with two Child objects A and B. Then I remove child A from parent collection (.getChildren().remove(A)) and call session.saveOrUpdate(P) to save Parent object. As all-delete-orphan cascade is set, the parent object is saved with one child and another removed child (A) is removed from DB. It is correct behaviour.

As I understand when hibernate loads such object (P) it wraps its children list into some Persistent collection (e.g. PersistentSet) and all manipulations with this collection are intercepting by hibernate and this allows it to decide which children should be deleted orphanly from db.

But.. I have the follow project architecture:

After the entity is loader from db (DO object) it is passed to service (facade object) where it is converted TO object using Dozer framework. After transformation persistent collection from DO object is converted to simple ArrayList in TO. Then it is passed to UI where it can be modified (remove child A from children collection). When we wand to save it we pass it to facade, where using Doser it is converted back to DO object, then we save it to DB (using session.saveOrUpdate).

In this case cascading doesn't work and removed child is not orphaned. It still presented in db.

Cascading works only if we call .merge insted of saveOrUpdate. I assume it is because hibernate automatically binds our object to the session and then make update for it.

So, can anyone describe me this behavior? Is it possible to support delete-orphan cascading using such DO -> TO -> DO transformation?

This is just common scenario and common question. If required I will be able to attach code/mappings etc.

1

There are 1 answers

0
Firo On

session.saveOrUpdate is for tracked entities, session.merge is for untracked entites

session.merge is meant for this scenario. You have an untracked entity with changes which should be written back. merge will load entities based on the id's of the objects(note: cascading) you give it and will copy the state over to these tracked entities and changes would be saved on next flush.