.net - NHibernate - When adding an object to a many-to-many collection, existing objects are removed and reinserted -
i'm using many-to-many mapping table maps fields objects.
relevant db structure...
objects: table
(pk) objectid
[ rest irrelevant ]
fields: table
(pk) fieldid
[ rest irrelevant ]
objectfields: table
(pk) fieldobjectid (fk) fkobjectid -> objects (fk) fkfieldid -> fields
my mapping looks this:
<bag name="fields" table="objectfields" lazy="true" cascade="all"> <key column="fkobjectid"/> <many-to-many class="field" column="fkfieldid" /> </bag>
now, collection operations work expect - retrieving, adding , deleting. however, there odd thing happening. if add object "fields" collection, nhibernate deletes there , reinserts it.
here log4net dump: debug nhibernate.sql [(null)] - select this_.objectid objectid6_0_, this_.name name6_0_, this_.description descript3_6_0_, this_.rootelement rootelem4_6_0_, this_.childelement childele5_6_0_, this_.imageurl imageurl6_0_, this_.haschildren haschild7_6_0_, this_.createstamp createst8_6_0_ objects this_ this_.objectid = @p0;@p0 = 5 [type: int32 (0)]
debug nhibernate.sql [(null)] - select fields0_.fkobjectid fkobjectid1_, fields0_.fkfieldid fkfieldid1_, inventoryf1_.fieldid fieldid4_0_, inventoryf1_.fieldname fieldname4_0_, inventoryf1_.fieldtype fieldtype4_0_, inventoryf1_.required required4_0_ objectfields fields0_ left outer join fields inventoryf1_ on fields0_.fkfieldid=inventoryf1_.fieldid fields0_.fkobjectid=@p0;@p0 = 5 [type: int32 (0)]
debug nhibernate.sql [(null)] - select this_.fieldid fieldid4_0_, this_.fieldname fieldname4_0_, this_.fieldtype fieldtype4_0_, this_.required required4_0_ fields this_ this_.fieldid = @p0;@p0 = 2 [type: int32 (0)]
debug nhibernate.sql [(null)] - delete objectfields fkobjectid = @p0;@p0 = 5 [type: int32 (0)]
debug nhibernate.sql [(null)] - insert objectfields (fkobjectid, fkfieldid) values (@p0, @p1);@p0 = 5 [type: int32 (0)], @p1 = 1 [type: int32 (0)]
debug nhibernate.sql [(null)] - insert objectfields (fkobjectid, fkfieldid) values (@p0, @p1);@p0 = 5 [type: int32 (0)], @p1 = 2 [type: int32 (0)]
as can see, it's issuing delete statements , reinserting.
any ideas how prevent this?
in short, bags behave that, should use type of collection. here have explanation nhibernate doc remomend read whole chapter (17.5. understanding collection performance
all indexed collections (maps, lists, arrays) have primary key consisting of , index columns. in case collection updates extremely efficient - primary key may efficiently indexed , particular row may efficiently located when nhibernate tries update or delete it.
sets have primary key consisting of key , element columns. may less efficient types of collection element, particularly composite elements or large text or binary fields; database may not able index complex primary key efficently. on other hand, 1 many or many many associations, particularly in case of synthetic identifiers, efficient. (side-note: if want schemaexport create primary key of set you, must declare columns not-null="true".)
idbag mappings define surrogate key, efficient update. in fact, best case.
bags worst case. since bag permits duplicate element values , has no index column, no primary key may defined. nhibernate has no way of distinguishing between duplicate rows. nhibernate resolves problem removing (in single delete) , recreating collection whenever changes. might inefficient.
Comments
Post a Comment