NHibernate Pitfalls: One Shot Delete and Inverse Collections

This is part of a series of posts about NHibernate Pitfalls. See the entire collection here.

When you clear all items in an entity’s collection by calling it’s Clear() method, if it has cascading option all-delete-orphan, NHibernate will then delete (when flushing) all of the collection’s items. That is because it considers them to be children of the entity and we explicitly told NHibernate that the entity no longer has any (very sad, I know! Winking smile).

Ideally, we would expect NHibernate to only issue a single DELETE, as this:

   1: DELETE FROM children
   2: WHERE parent_id = @p0
   3: /*
   4: AND some_filter_value = @p1
   5: */

That, however, is not the case for inverse collections, which are the most common ones. In this case, NHibernate issues N DELETEs, one for each entity, which is bad in terms of performance:

   1: DELETE FROM children
   2: WHERE children_id = @p0;
   4: DELETE FROM children
   5: WHERE children_id = @p1;
   7: -- and so on

The NHibernate reference has an incorrection, in which it states exactly the opposite:

“one-shot-delete apply to collections mapped inverse="true"”

There is an open issue at NHibernate JIRA meant to fix this, https://nhibernate.jira.com/browse/NH-3708, but it is not so simple, so we’ll have to wait! Sad smile

In the meantime, even though it’s not so intuitive, you can use one of the delete methods I describe in this post.


No Comments

Add a Comment

As it will appear on the website

Not displayed

Your website