Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

nhibernate does not cascade delete children

The scenario is as follows,

I have 3 objects (i simplified the names) named Parent, parent's child & child's child
parent's child is a set in parent, and child's child is a set in child.

mapping is as follows (relevant parts)

parent

<set name="parentset"
     table="pc-table"
     lazy="false"
     fetch="subselect"
     cascade="all-delete-orphan"
     inverse="true">
  <key column=FK_ID_PC" on-delete="cascade"/>
  <one-to-many class="parentchild,parentchild-ns"/>
</set>

parent's child

<set name="childset"
     table="cc-table"
     lazy="false"
     fetch="subselect"
     cascade="all-delete-orphan"
     inverse="true">
  <key column="FK_ID_CC" on-delete="cascade"/>
  <one-to-many class="childschild,childschild-ns"/>
</set>

What i want to achieve is that when i delete the parent, there would be a cascade delete all the way trough to child's child. But what currently happens is this.

(this is purely for mapping test purposes) getting a parent entity (works fine)

IQuery query = session.CreateQuery("from Parent where ID =" + ID);
IParent doc = query.UniqueResult<Parent>();

now the delete part

session.Delete(doc);
transaction.Commit();

After having solved the 'cannot insert null value' error with cascading and inverse i hopes this would now delete everything with this code, but only the parent is being deleted.

Did i miss something in my mapping which is likely to be missed? Any hint in the right direction is more than welcome!


Diego, thank you for the to the point answer. (and explanation)

I went with removing the on-delete="cascade", this because I like as much control as possible in code and not in the database.

The code posted below is the (working) result.

parent

<set name="parentset"     
     table="pc-table"     
     cascade="all-delete-orphan"     
     inverse="true"
     batch-size="5">     
  <key column=FK_ID_PC"/>     
  <one-to-many class="parentchild,parentchild-ns"/>     
</set>

parent's child

<set name="childset"            
     table="cc-table"     
     cascade="all-delete-orphan" 
     batch-size="5"  
     inverse="true">            
  <key column="FK_ID_CC">            
  <one-to-many class="childschild,childschild-ns"/>            
</set>

Hope this helps people with the same problem!

like image 311
marn Avatar asked Mar 05 '10 15:03

marn


People also ask

Should I use delete cascade?

Should we use on delete cascade? Yes, the use of ON DELETE CASCADE is fine, but only when the dependent rows are really a logical extension of the row being deleted.

What is cascade function in SQL?

CASCADE in SQL is used to simultaneously delete or update an entry from both the child and parent table.


1 Answers

By setting on-delete="cascade" on the keys, you are letting the DB handle the cascading.

Are you generating your schema with NHibernate?

I just reproduced your example and it worked fine with and without that attribute. When removing it, NHibernate does the cascading.

BTW, using lazy="false" fetch="subselect" is not something that you should do by default. If you remove those attributes, leave on-delete="cascade" and change cascade to save-update, you'll only have two queries to retrieve and delete a Parent.

like image 77
Diego Mijelshon Avatar answered Sep 18 '22 17:09

Diego Mijelshon