How to force NHibernate not to update all objects in a collection

How to force NHibernate not to generate UPDATE for each item in the collection if I change only one item of this collection. Here he is:

internal class Master { private int _id; public string Name { get; set; } public ISet<Slave> Slaves { get; set; } public Master() { Slaves = new HashedSet<Slave>(); } } internal class Slave { private int _id; public string Name { get; set; } public Master Master { get; set; } } 

Mapping:

 <class name="nHibernateTutorials.Slave, nHibernateTutorials" lazy="false"> <id access="field" name="_id" column="id"> <generator class="native"/> </id> <property access="property" name="Name" column="name"/> <many-to-one access="property" name="Master" column="master"/> </class> <class name="nHibernateTutorials.Master, nHibernateTutorials" lazy="false"> <id access="field" name="_id" column="id"> <generator class="native"/> </id> <property access="property" name="Name" column="name"/> <set access="property" name="Slaves" cascade="save-update"> <key column="master"/> <one-to-many class="nHibernateTutorials.Slave, nHibernateTutorials"/> </set> </class> 

Code updating a collection item:

 Master m = new Master {Name = "Kenny"}; Slave s1 = new Slave { Name = "Cartman", Master = m}; m.Slaves.Add(s1); Slave s2 = new Slave {Name = "Kyle", Master = m}; m.Slaves.Add(s2); Slave s3 = new Slave {Name = "Stan", Master = m}; m.Slaves.Add(s3); DbManager.SaveObject(m); s1.Name = "Daisy"; DbManager.SaveObject(m); 

The code in DbManager.SaveObject simply opens a new session and uses SaveOrUpdate to update the object.

If I change one of the elements from the collection of subordinate masters and then try to update the master, NHibernate generates SQL to update all the elements in the Slaves collection. But I need to update only one item.

Thanks.

+3
source share
3 answers

You probably see redundant many-to-one updates. When you map one-to-many collections, you must choose which side owns the relationship. In your example, both sides of the relationship believe that it belongs to them!

You need to add the attribute to your set element with inverse="true" . This directive tells NHibernate not to update the collection from this end of the relationship.

+1
source

Try using access = "backfield" instead of access = "property".

0
source

You save the temporary collection because Master.Slaves is still the original collection.

This will not happen in a new session.

If you want to update the object in the same session after saving, you must execute session.Refresh () this object. Your DBManager.SaveObject method might update after saving.

 DbManager.SaveObject<T>( T entity ) { session.Save( entity ); session.Refresh( entity ); } 
0
source

All Articles