Каскадное удаление NHibernate в связанных подклассах - PullRequest
0 голосов
/ 04 августа 2011

Я сейчас работаю над небольшим PoC-проектом и решил взять NHibernate за спин для персистентной части.

Я определил следующие доменные объекты:

  • Местоположение : аннотация класс, представляющий местоположение (корень дерева местоположений)
  • FixedLocation : аннотация класс, представляющий географически фиксированное местоположение (происходит от Location)
  • Страна : представляет страну (происходит из Местоположения)
  • Город : представляет город в стране (происходит из Местоположения и не может логически существовать без Страны)

Требования:

  1. Все местоположения должны в конечном итоге быть производными от Location (относительно, все потомки Location будут использовать один и тот же диапазон ключей базы данных)
  2. A двунаправленная связь между страной и городом должна существовать
  3. Удалять следует каскадно по всему дереву сущностей, например удаление страны также должно удалить связанные города

Вот как я отобразил вышеупомянутые классы

    <?xml version="1.0" encoding="utf-8" ?> 
    <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="AET.PoC.Domain" namespace="AET.PoC.Domain.Entities">    
    <class name="Location" table="Locations" abstract="true">
       <id name="Id" type="Int64" unsaved-value="0">
         <generator class="native" /> 
       </id>
       <property name="LocationType" access="readonly" /> 
    </class>
    <joined-subclass name="FixedLocation" table="FixedLocations" extends="Location" abstract="true">
         <key column="LocationId" /> 
         <component name="GPSPosition" class="GPSPosition">
             <property name="Latitude" type="double" /> 
             <property name="Longitude" type="double" /> 
         </component>
    </joined-subclass>
 <joined-subclass name="Country" table="Countries" extends="FixedLocation">
  <key column="FixedLocationId" /> 
  <property name="Name" length="50" not-null="true" /> 
 <set name="CitySet" cascade="all, delete-orphan" inverse="true">
  <key column="CountryId" foreign-key="FK_City_Country" on-delete="cascade" /> 
  <one-to-many class="City" /> 
  </set>
  </joined-subclass>
 <joined-subclass name="City" table="Cities" extends="FixedLocation">
  <key column="FixedLocationId" /> 
  <many-to-one name="Country" class="Country" column="CountryId" not-null="true" cascade="all, delete-orphan" /> 
  <property name="Name" length="50" not-null="true" /> 
  </joined-subclass>
  </hibernate-mapping>

Отображение этих классов таким образом удовлетворяет вышеуказанным требованиям или, по крайней мере, частично ...

Когда я удаляю () объект Country (скажем, идентификатор местоположения 1), который имеет 2 связанных объекта City (скажем, идентификаторы местоположения 2 и 3), это происходит так:

  1. Запись с FixedLocationId = 1 удаляется из таблицы стран
  2. Записи с FixedLocationId = 2 и 3 удаляются из таблицы городов
  3. Запись с LocationId = 1 удаляется из таблицы FixedLocations
  4. Запись с Id = 1 удаляется из таблицы Locations

Пока все хорошо, но ...

  1. Записи с LocationId = 2 и 3 не удалены из таблицы FixedLocations
  2. Записи с Id = 2 и 3 не удалены из таблицы Locations

Что я здесь не так делаю? Можно ли это сделать в первую очередь?

Я попытался установить атрибут on-delete = "cascade" в тегах, но это заставило NHibernate жаловаться на то, что круговой каскад не разрешен ...

1 Ответ

0 голосов
/ 04 августа 2011

Не ставьте каскады на многие-к-одному в Сити. Вместо этого убедитесь, что каждое местоположение знает о дочерних местоположениях:

<class name="Location" table="Locations" abstract="true">
    ....
    <many-to-one name="_parent" column="ParentLocationID" />
    ....
    <set name="_childLocations" table="Locations" inverse="true" cascade="all-delete-orphan" >
        <key column="ParentLocationID" />
        <one-to-many class="Location"/>
    </set>
    ....
</class>

Таким образом, ваша иерархия и жизненный цикл объектов работают и располагаются правильно. Вы можете принять другие требования в подклассах.

...