1

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

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

为简单起见,假设有一个包含角色列表(包)的用户对象。我想要它,这样我就可以拥有一个 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>

进行此设置并运行它后,当我将新角色添加到用户对象的集合中时,我无法保存要保存的 ObjectType 字段。它在 ObjectToRole 表中保存了一个新条目,但 ObjectType 为空。看着袋子,它不会将它加载到集合中。我想我已经把它缩小到设置不正确的子类结构或者包设置不正确。我倾向于这个包,因为我认为它可能只是将集合视为一堆抽象类而不是子类 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 是一个身份字段,并且是这样指定的。我完全不知所措。

4

1 回答 1

2

好的!在玩了很多映射文件之后,我发现了一个未记录的问题(至少我找不到提到我所犯的错误)。

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

The bag seems to be an issue that is not controllable through anything I have found in documentation. I cannot find another instance of where the abstract class is saved through the mapping. It appears that NHibernate does not know that the linking class is a UserInRole object and not a ObjectInRole object. Researching all the options that are provided for the bag node there was no apparent way to tell NHibernate what type of class it was linking through to make the many-to-many association. From what I can tell it doesn't care, but more or less treats the table as just a table, not a mapped object. If there was a way to tell it append something for the insert then maybe it would be possible, but I have not seen any information regarding this.

于 2009-03-21T01:07:55.423 回答