Reputation: 93
I am trying to update an nHibernate object with a child collection using the .Update() method found on a hibernate session. The only thing that I can do with the current setup is add children, I can not modify them or remove them.
For clarification the objects and their mapping are as follows:
public class Parent {
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual ISet<Child> Children { get; set; } = new HashSet<Child>();
}
public class ParentMap: ClassMap<Parent>
{
public ParentMap()
{
Id(x => x.Id);
Map(x => x.Name);
HasMany(x => x.Children)
.AsSet()
.Inverse()
.Cascade.AllDeleteOrphan();
}
}
public class Child {
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual Parent Parent { get; set; }
}
public class ChildMap: ClassMap<Child>
{
public ChildMap()
{
Id(x => x.Id);
Map(x => x.Name);
References(x => x.Parent);
}
}
When I get changes from my UI layer and try to update the already existing object using:
using (var tx = _session.BeginTransaction())
_session.Update(newParent);
tx.Commit();
}
Here newParent is a transient object (obtained from the database in an earlier session andd shown in the UI) containing the same identifier as the object I would like to update, but with changes to the child collection. Somehow using this approach I can only add children, but not modify or remove them.
Where is my mistake?
Upvotes: 2
Views: 1428
Reputation: 3331
Most likely what is happening to you, is that instead of modifying the set that NHibernate has instantiated in your Parent entity, you are replacing it all together by a new instance of HashSet
.
When you save or get an entity from NHibernate, your Children ISet
gets loaded with an instance of a PersistentGenericSet
(that implements ISet
) which has the responsibility of helping with this change tracking for your collection.
In short, do not assign to the Children property. In fact, make the setter protected
.
Just Add()
or Remove()
or Clear()
it as required.
Upvotes: 2