Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NHibernate remove item in collection not working

I'm a newbie in the NHibernate world.

Why this code works removing the territory from the collection:

Country country;

using (IUnitOfWork unit = UnitOfWork.Start())
{
    country = new Country();
    country.Name = "My country";

    Territory territory = new Territory();
    country.Territories.Add(territory);
    country.Territories.Remove(territory);
}

And this code is not working:

Country country;

using (IUnitOfWork unit = UnitOfWork.Start())
{
    country = _countries.GetById(1);

    Territory territory = new Territory();
    country.Territories.Add(territory);
    country.Territories.Remove(territory);
}

In the second code snippet, _countries is a repository. The country ID 1 exists in the database. The territory is added, but never removed...

Here's the mapping:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="iCible.Artishows.Framework.ObjectDefinition"
                   namespace="iCible.Artishows.Framework.ObjectDefinition" >
  <class name="Country" >
    <id name="ID">
      <generator class="identity"/>
    </id>
    <property name="Name" />
    <set name="Territories" cascade="all-delete-orphan" inverse="true" order-by="Name" sort="iCible.Artishows.Framework.ObjectDefinition.TerritoryComparer">
      <key column="COUNTRYID"/>
      <one-to-many class="Territory"/>
    </set>
    <property name="CreationDate" />
    <property name="EditionDate" />    
    <many-to-one class="User" name="CreationUser"/>
    <many-to-one class="User" name="EditionUser"/>
  </class>
</hibernate-mapping>

What am I missing here?

like image 410
vIceBerg Avatar asked Feb 28 '23 10:02

vIceBerg


1 Answers

I'm not entirely clear on the reason why, but I think it might be because of the inverse="true" part. The implication of having that, I think, is that it means the relationship is managed by the other side, i.e. from the Territory to the Country, so deleting the item from the Country.Territories may not work exactly as you expect.

What does your Territory mapping look like? - I assume it has a many-to-one reference to the Country parent?

Having said that, my NHibernate knowledge is still mostly at the level of "fiddle with the settings until it works like I want it to". But I'm pretty sure you'll be able to make it work by adjusting either the inverse attribute and/or the cascade option (i.e. try changing it to "all").

For what it's worth, most of our mappings that use one-to-many look like this, and I think we usually delete things in the same way as you showed:

<class name="Parent">
  <id name="ParentID">
  ...
  <map name="ChildCollection" cascade="all" inverse="true">
</class>

<class name="Child">
  ...
  <many-to-one name="Parent" column="ParentID" not-null="true">
</class>
like image 146
Gavin Avatar answered Mar 08 '23 12:03

Gavin