mridula
mridula

Reputation: 3281

NHibernate running unnecessary UPDATE command after INSERT - Unidirectional Many-To-One relationship

I have a uniderational many-to-one relationship from Claim to Brand. (One claim has one brand associated with it).

Following is the mapping, which works fine -

Claim.hbm.xml:

<many-to-one name="Brand" class="Brand" column="BRAND_CODE" />

However, when I save a claim, like this -

var c = new Claim();
//Assign other properties to claim.
session.Get<Brand>(brandId);
c.Brand = brand;
session.SaveOrUpdate(c);

After an insert command in the CLAIM table, nhibernate also runs an unnecessary update command on the BRAND table. Although this may not be an issue in most cases, I am working with a legacy database that has triggers on update of the BRAND table. I do not want these triggers to run.

From NHibernate's Log:

INSERT INTO JLL$SECSALES.SEC_STOCKIST_CLAIM_DET (ACTIVITY_CODE, COMP_CODE, COST_LEVEL1, COST_LEVEL2, FROM_DATE, TO_DATE, CLAIM_AMT, APPROVED_AMT, CLAIM_STATUS, REMARKS, VARIANCE, ACTIVITY_TYPE_ID, STOCKIST_CLAIM_ID_DET_ID, STOCKIST_CLAIM_ID) VALUES (:p0, :p1, :p2, :p3, :p4, :p5, :p6, :p7, :p8, :p9, :p10, :p11, :p12, :p13);:p0 = 'ACT123' [Type: String (6)], :p1 = 'ACCDEP' [Type: String (6)], :p2 = 'DIV0000006' [Type: String (10)], :p3 = 'ABLE CHERIYAN K C ( E000005577 )' [Type: String (32)], :p4 = 01/28/2014 12:00:00 AM [Type: DateTime (0)], :p5 = 01/28/2014 12:00:00 AM [Type: DateTime (0)], :p6 = 0 [Type: Single (0)], :p7 = 0 [Type: Single (0)], :p8 = 'N' [Type: StringFixedLength (1)], :p9 = 'AAA' [Type: String (3)], :p10 = 0 [Type: Single (0)], :p11 = NULL [Type: Int64 (0)], :p12 = 1 [Type: Int64 (0)], :p13 = 12 [Type: Int64 (0)]
UPDATE JLL$TRAN.BRAND_MAST SET BRAND_DESC = :p0, REC_STATUS = :p1, ADDDATE = :p2, MODDATE = :p3, AUTHDATE = :p4, ADDUSER = :p5, MODUSER = :p6, AUTHUSER = :p7 WHERE BRAND_CODE = :p8;:p0 = 'BOXER' [Type: String (5)], :p1 = 'A' [Type: StringFixedLength (1)], :p2 = 12/28/2009 1:41:38 PM [Type: DateTime (0)], :p3 = 01/01/0001 12:00:00 AM [Type: DateTime (0)], :p4 = 12/28/2009 1:41:41 PM [Type: DateTime (0)], :p5 = 'PRADOSH' [Type: String (7)], :p6 = NULL [Type: String (0)], :p7 = 'PRADOSH' [Type: String (7)], :p8 = 'BND0000022' [Type: String (10)]

I have tried insert="false", update="false", cascade="none" on the many-to-one relationship, but in vain. How can I prevent the unnecessary update statement?

Upvotes: 0

Views: 458

Answers (3)

DerHaifisch
DerHaifisch

Reputation: 476

Brand is a model which our application will never change. It is just used in many-to-one relationships with multiple tables. I just removed the mapping of all the unnecessary columns of the brand table from the Brand model, and it worked. I did not understand why, but it worked!

I ran into an issue similar to this where there was a one-to-many relationship between two entities. I had the collection end marked with Inverse(). Whenever I inserted a new child entity, NHibernate would immediately issue an update for the parent entity. This update was then blowing up because of an integrity issue on one of the fields.

I took a close look at the SQL and the table and came to the realization that there were a significant number of fields with numeric values that were marked as nullable in the table, but not in the class to which the table was mapped. The issue was that NHibernate was dutifully converting the nulls to zeroes. Because the field actually had a value now where before it was null, it marked those fields as dirty and justifiably attempted an update of the record in the database. The solution was to go back to the class and mark the numeric properties as nullable. Once I completed this task, I recompiled and no more update after the insert.

The fact that the removal of your fields caused the insert to "go away" indicates that there was something wrong with those fields and may have been something similar to what I experienced.

Upvotes: 1

Frederik Gheysels
Frederik Gheysels

Reputation: 56934

You need to set the inverse attribute of the bag or set element in the NH mapping.

http://blog.lowendahl.net/data-access/managing-parentchild-relationships-with-nhibernate-inverse-management/

Upvotes: 1

Jamie Ide
Jamie Ide

Reputation: 49261

Enable dynamic updates on the class so that only the changed properties are updated. This will tell you which properties NHibernate has detected as dirty and should allow you to troubleshoot why the property is changing after the save.

<class ... dynamic-update="true">

Upvotes: 0

Related Questions