NHibernate 级联删除关联的连接子类
我目前正在开发一个小型 PoC 项目,并决定使用 NHibernate 来尝试持久性部分。
我定义了以下域实体:
- Location:abstract 表示位置的类(位置树的根)
- FixedLocation:abstract< /em> 代表地理位置的类(源自 Location)
- Country:代表一个国家(源自 Location)
- City:代表一个国家内的城市(源自 Location)并且在逻辑上不存在 所有位置最终都必须从位置
要求:
- 派生(相对而言,所有位置后代将共享相同范围的数据库键)
- 国家和城市之间应存在双向关系
- 删除应在整个实体中级联树,例如删除一个国家/地区也应该删除关联的城市
以下是我如何映射上述类
<?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>
以这种方式映射这些类满足上述要求,或至少部分满足...
当我删除()一个国家/地区时实体(例如位置 ID 1)有 2 个关联的 City 对象(例如位置 ID 2 和 3),会发生以下情况:
- 带有 FixedLocationId=1 的记录从国家表中删除
- 带有 FixedLocationId=2 和 3< 的记录< /em> 从 Cities 表中删除
- LocationId=1 的记录从固定位置表中删除
- Id=1 的记录从 Locations 表中删除
到目前为止,很好,但是...
- LocationId=2 和 3 的记录未从固定位置表中删除
- Id=2 和 3 的记录> 是否未从位置表中删除
我在这里做错了什么?首先可以做到这一点吗?
我尝试在标签中设置 on-delete="cascade" 属性,但这使得 NHibernate 抱怨不允许循环级联...
I'm currently working on a small PoC project and decided to take NHibernate for a spin for the persistence part.
I have defined the following domain entities:
- Location: abstract class representing a location (root of the location tree)
- FixedLocation: abstract class representing a geographically fixed location (derives from Location)
- Country: represents a country (derives from Location)
- City: represents a city within a country (derives from Location and cannot logically exist without a Country)
Requirements:
- All locations must ultimately derive from Location (relationally, all Location descendants will share the same range of database keys)
- A bidirectional relationship should exist between Country and City
- Deletes should cascade throughout the entity tree, e.g. deleting a Country should also delete the associated Cities
Here's how I mapped the above classes
<?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>
Mapping these classes this way fullfils the above requirements, or at least partially...
When I Delete() a Country entity (say location ID 1) that has 2 associated City objects (say location IDs 2 and 3), this is what happens:
- The record with FixedLocationId=1 is deleted from the Countries table
- The records with FixedLocationId=2 and 3 are deleted from the Cities table
- The record with LocationId=1 is deleted from the FixedLocations table
- The record with Id=1 is deleted from the Locations table
So far, so good, but...
- The records with LocationId=2 and 3 are not deleted from the FixedLocations table
- The records with Id=2 and 3 are not deleted from the Locations table
What am I doing wrong here? Can this be done in the first place?
I tried setting the on-delete="cascade" attribute in the of the tags but that made NHibernate complain about circular cascading not being allowed...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
不要在 City 中进行多对一级联。相反,请确保每个位置都知道子位置:
这样您的层次结构和对象生命周期就可以正常工作和级联。您可以在子类中满足其他要求。
Do not put cascades on many-to-one in City. Instead make sure that every location knows about child locations:
This way you have your hierarchy and objects life cycle working and cascaded properly. You can take of other requirements in subclasses.