NOtherDev
NOtherDev

Reputation: 9672

Why NHibernate deletes referenced objects one by one, not using foreign key?

I have simple Parent-Child relationship, Parent has many Child objects, the relation is unidirectional:

public class Parent
{
    public virtual int Id { get; protected set; }
    public virtual string Name { get; set; }
    public virtual IList<Child> Children { get; set; }
}

public class Child
{
    public virtual int Id { get; protected set; }
    public virtual string Name { get; set; }
}

Mapping for the relation sets cascade to AllDeleteOrphan to remove Child objects not referenced by Parent any more:

HasMany(x => x.Children).Cascade.AllDeleteOrphan();

And now I'm clearing the list of Child objects:

var parent = session.Get<Parent>(1);
parent.Children.Clear();
session.Update(parent);

NHibernate deletes the Child object as expected, but it do this by sending separate DELETE query for each Child from the collection: DELETE FROM Child WHERE Id = ... - that can mean really LOT of queries.

Anyway, it can be easily done using single query like DELETE FROM Child WHERE ParentId = 1. Why NHibernate is not using the parent foreign key to clear the collection? It seems that it knows everything to prepare such query (which foreign key, what value etc.)?

Upvotes: 5

Views: 973

Answers (2)

Firo
Firo

Reputation: 30813

NHibernate issues a NHibernate: UPDATE "Child" SET Parent_id = null WHERE Parent_id = @p0;@p0 = 1 before deleting the childs. Since the has many is not inverse the parent has to unset the association and then cascades the delete to the child because the chuild may have other cascades set which have to be deleted.

However even with inverse one shot deletes do not work. NH only seems to delete at once with element/component collections.

One reason can be childs could have user defined sqldeletes, additional cascaded properties and so on. The easiest way for NH is to simply cascade the delete to each child seperatly.

Upvotes: 0

Diego Mijelshon
Diego Mijelshon

Reputation: 52735

NHibernate can and will do that in certain cases.

It's all explained here.

Upvotes: 2

Related Questions