0
votes

If you see the documentation for performance of the collections : http://nhibernate.info/doc/nhibernate-reference/performance.html#performance-collections-taxonomy

It says:

Bags are the worst case. Since a bag permits duplicate element values and has no index column, no primary key may be defined. NHibernate has no way of distinguishing between duplicate rows. NHibernate resolves this problem by completely removing (in a single DELETE) and recreating the collection whenever it changes. This might be very inefficient.

However I cannot confirm this case. For example if I have a simple parent child relation with cascade all, using bag, with the following code:

    using (var sf = NHibernateHelper.SessionFactory)
        using (var session = sf.OpenSession())
        {
            var trx = session.BeginTransaction();
            var par = session.Query<Parent>().First();
            var c = new Child { Id = 4, Name = "Child4" };
            par.Children.Add(c);
            trx.Commit();
        }

I don't see any deletes, but an insert to child table and an update for parentid. This actually make sense. However it seems to contradict with the docs. What am I missing?

1
NHibernate can sometimes figure out which Entity (and related relation Table Row/Column) you are referring to using Ids like your Child has (I assume it's a transient and mapped object in itself). I don't have time right now, but I suspect if you try it with a List<string> mapped to a Bag, so you end up with a relation Table that has just two Columns, 'Parent_id' and 'StringValue' (with repeated strings present) you will see the documentation described behavior. - starlight54
@starlight54, If that's true then my conclusion is the above documentation is only valid for collections of values and components. - Onur Gumus
That seems correct to me, it might also apply on a many-to-many Relation Table with Columns 'EntityA_id' and 'EntityB_id' (and one side was mapped as Bag, not Inverse) if NHibernate was not aware of any other constraints, although then it might also throw an Exception upon adding a duplicate transient Entity on either side if it enforces Entity uniqueness in any Collection, I'm not certain on that either, my Nhib is a touch rusty at the moment :) - starlight54

1 Answers

0
votes

The example you give is almost exactly like the efficient case documented in the NHibernate reference at 19.5.3. Bags and lists are the most efficient inverse collections.