Cascading in (N)Hibernate, which rules do I need?
-
19-09-2019 - |
Question
Sorry if this is a dupe, couldn't find it but didnt really know what to search for, anyway...
I have three classes, Parent
, Child
and Other
Parent
has many Child
where child has a Parent_Id
column
Other
holds a reference to a Child
through a Child_Id
column
When I delete a Parent
, I also want to delete all the associated Child
objects. If these Child
objects are referenced by any Other
classes, I want their (the Other
objects) Child_Id
references to be nullified.
What cascade rules do I need on the two relationships?
Also, will NHibernate update entities in-memory as well as in the database?
I.e. if I have a bunch of Parent
, Child
and Other
in memory (i.e. loaded from db, not transient) and tell NH to delete a Parent
, what will happen? I assume the Parent
and Child
objects will become transient? What will happen to the Child
property of any Other
objects?
Edit: when using All-Delete-Orphan, what classes an object as an orphan? In the example above, is a Child
an orphan if its parent Parent
is deleted? Does the reference from Other
matter when considering an entity as orphaned?
Thanks
Solution
NH does not update any of your entities in memory (except of Ids and Versions). NH is not responsible to manage the relations of you entities. It just persists what you did in memory to the database.
From this point of view it should become easier to understand.
cascade="delete"
means that when the parent is deleted, the child gets deleted as well.
cascade="delete-orphan"
means, that additionally, the child is even deleted if no parent references it anymore. This, of course, only works if the child is in the session.
The deleted instance gets transient in memory. References to the transient instance (from Other
) will cause an exception. AFAIK, you need to remove reference to deleted instances by yourself. You probably can make it implicit by some tricks, but I doubt that this will be clean. It's business logic.
For parent-child relations, cascade="all-delete-orphan"
is appropriate.
For regular reference I prefer cascade="none"
.
There is a great explanation by Ayende Rahien