In nhibernate, unable to update list of child objects

I have x , which is an object of type objectX , which has a ListOfObjectYs property, which

List<objectY> 

nhibernate mapping is as follows:

  public ObjectXMap() { HasMany(x => x.ListOfObjectYs).AsBag().Inverse(); } 

when I go to save it, I change some properties to objectX , and then:

  Session.SaveOrUpdate(x); 

Now I need to update this property, which is a list. I get a new list of objectYs, and I want to replace the existing list of objectsY with a new list. do i need to do this?

  foreach (ObjectY y in x.ListOfObjectYs) { Session.Delete(y); deleted = true; } if (deleted) { _session.Flush(); } x.ListOfObjectYs.Clear(); foreach (ObjectY y in newObjectYList) { x.ListOfObjectYs.Add(y); Session.SaveOrUpdate(y); } _session.Flush(); 

my questions:

  • Do I need to delete everything and erase before adding new ones.
  • Do all these incremental savings need to be done between

there is a better way to do this update where I need to update the object (s) and also update the properties that are listed where there is a whole new list (this means that the elements need to be removed and added).

+6
c # asp.net-mvc nhibernate fluent-nhibernate
source share
2 answers

The answers to your questions are no and no. If you want to replace the list, you must clear it and add new elements. If you have a cascade set for all-delete-orphan, as in James Kovac’s answer, changes to the collection will be saved when the session is cleared.

It's important to understand what Save, Update, and SaveOrUpdate mean in NHibernate:

  • Save - make the new object permanent.
  • Update - make the changed individual object permanent.
  • SaveOrUpdate - save or update depending on the unsaved value of the object identifier

See also Manipulating persistent data .

Assuming all your objects were loaded in the same session, then replacing the collection might be as simple as:

 x.ListOfObjectYs.Clear(); foreach (ObjectY y in newObjectYList) { x.ListOfObjectYs.Add(y); } _session.Flush(); 
+3
source share

You need a cascade on your HasMany (). If the children are wholly owned by the parent, Cascade.AllDeleteOrphan () is a good choice. This way, saving, updating, and deleting the parent is automatically cascaded to child objects, which eliminates the need for your complex foreach block. In this case, just update your collection and complete the transaction. NHibernate takes care of the rest.

UPDATE: to change the list, simply add and remove items from the list, as usual, with the .NET collection. For example:

 public void RemoveY(ObjectY someY) { ListOfObjectYs.Remove(someY); } public void AddY(ObjectY someY) { ListOfObjectYs.Add(someY); } public void ClearAllY() { ListOfObjectYs.Clear(); } 

When a transaction is committed, any changes to the ListOfObjectYs collection will be saved along with the parent ObjectX object.

+3
source share

All Articles