Hi all,
(Using NHibernate 1.2)
Am having trouble with excessive database activity. Have tracked the problem down to uni-directional lists (with cascade) that are generating an INSERT followed by an UPDATE for every element in the list. After investigation, this appears to be an NHibernate problem.
The following mapping is from the NHibernate GenericTest\ListGeneric\Simple test.
Code:
<class name="A" table="a" lazy="false">
<id name="Id" column="id" unsaved-value="null">
<generator class="native" />
</id>
<property name="Name" column="aname" />
<list name="Items" cascade="all-delete-orphan" generic="true">
<key column="a_id" />
<index column="a_idx" />
<one-to-many class="B" />
</list>
</class>
<class name="B" table="b" lazy="false">
<id name="Id" column="id" unsaved-value="null">
<generator class="native" />
</id>
<property name="Name" column="aname" />
</class>
This is then exercised with the following code:
Code:
A a = new A();
a.Name = "first generic type";
a.Items = new List<B>();
B firstB = new B();
firstB.Name = "first b";
B secondB = new B();
secondB.Name = "second b";
a.Items.Add(firstB);
a.Items.Add(secondB);
This results in the following
five SQL statements:
Code:
INSERT INTO a (aname) VALUES (@p0); select SCOPE_IDENTITY(); @p0 = 'first generic type'
INSERT INTO b (aname) VALUES (@p0); select SCOPE_IDENTITY(); @p0 = 'first b'
INSERT INTO b (aname) VALUES (@p0); select SCOPE_IDENTITY(); @p0 = 'second b'
UPDATE b SET a_id = @p0, a_idx = @p1 WHERE id = @p2; @p0 = '1', @p1 = '0', @p2 = '1'
UPDATE b SET a_id = @p0, a_idx = @p1 WHERE id = @p2; @p0 = '1', @p1 = '1', @p2 = '2'
Am I missing something or is this a serious problem with NHibernate? This is doubling the database activity for virtually every insert. Conceptually it also makes no sense since, when inserting a B, NHibernate knows both the Id of the parent A and the index value.
Why is it doing an Update, rather than passing all B columns in the Insert?
(My whole application is using lists rather than bags to ensure sequence is respected!!)