NHibernate单表继承

时间:2009-03-20 02:51:45

标签: nhibernate hibernate nhibernate-mapping

我在使用继承和NHibernate设置基于角色的结构时遇到了麻烦。

基本上我想要一个名为ObjectInRole的抽象类。此类(和相应的数据库表)包含RoleId,ObjectId和ObjectType(这将是鉴别器列)。鉴别器列将是获得该角色的对象类型。

为简单起见,假设有一个User对象包含Roles的列表(包)。我希望它能让我有一个UserInRole类,它将成为ObjectInRole的子类。

我这样创建了这个包:

<bag name="Roles" table="ObjectInRole" where="ObjectType = 'AthletesCafe.Core.Domain.System.Users.User, AthletesCafe.Core'" generic="true"
     access="field.pascalcase-underscore" lazy="true">
  <key column="ObjectId" />
  <many-to-many class="AthletesCafe.Core.Domain.System.Roles.Role, AthletesCafe.Core" column="RoleId" />
</bag>

我已将ObjectInRole的映射设置为:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="AthletesCafe.Core.Domain.System.Roles" assembly="AthletesCafe.Core">
  <class name="ObjectInRole" table="ObjectInRole" lazy="true" abstract="true">
<id name="ID" type="Int32" unsaved-value="0">
  <column name="ID" not-null="true" unique="true" index="PK_ObjectInRole"/>
  <generator class="identity" />
</id>
<discriminator column="ObjectType" type="String" insert="true" force="true"/>
<property name="ApplicationName" column="ApplicationName" type="String" not-null="false" length="255" />
<property name="ObjectId" column="ObjectId" type="int" not-null="true" />
<property name="ObjectType" column="ObjectType" type="String" />

<many-to-one name="Role" column="RoleId" class="AthletesCafe.Core.Domain.System.Roles.Role, AthletesCafe.Core" not-null="true" cascade="none" />

<subclass name="AthletesCafe.Core.Domain.System.Roles.UserInRole" 
          discriminator-value="AthletesCafe.Core.Domain.System.Users.User, AthletesCafe.Core">
  <many-to-one name="User" column="ObjectId" class="AthletesCafe.Core.Domain.System.Users.User, AthletesCafe.Core" not-null="false" cascade="none" />
</subclass>

进行此设置并运行它时,当我向User对象的集合添加新角色时,我无法获取要保存的ObjectType字段。它在ObjectToRole表中保存了一个新条目,但ObjectType为null。看着包包,它不会加载到收藏中。我想我已经把它缩小到子类结构设置不正确或者包安装不正确。我倾向于我认为它可能只是将集合视为一堆抽象类而不是子类UserInRole。

请提供您对这两个领域的看法。谢谢!

编辑:

因此,我没有尝试添加到包(User.Roles.add(Role))并且让多对多持久化链接对象,而是决定将对象直接添加到表中。我收到了一个新错误:

null id in AthletesCafe.Core.Domain.System.Roles.UserInRole entry (don't flush the Session after an exception occurs) 

如果查看上面的类,我已经设置了User对象和Role对象。 id是一个标识字段,并且如此指定。我完全失去了。

1 个答案:

答案 0 :(得分:2)

OK!在大量使用映射文件后,我发现了一个未记录的问题(至少我没有发现我提交的错误)。

使用子类时,父类不能包含作为鉴别器列的属性的映射。如果你查看我发布的第二个映射文档,它会显示超类和子类。超类的鉴别器是ObjectType列。我还将它作为属性映射到抽象类ObjectInRole。你不能做这个。一旦这条线被移除,一切正常(不保存袋)。

这个包似乎是一个无法通过我在文档中找到的任何东西来控制的问题。我找不到通过映射保存抽象类的位置的另一个实例。似乎NHibernate不知道链接类是UserInRole对象而不是ObjectInRole对象。研究为bag节点提供的所有选项,没有明显的方法告诉NHibernate它通过什么类型的类连接来进行多对多关联。从我可以告诉它并不关心,但或多或​​少将表视为一个表,而不是映射对象。如果有一种方法可以告诉它为插入添加一些内容,那么也许它是可能的,但我还没有看到任何关于此的信息。