2009-03-20 3 views
1

У меня возникли проблемы с созданием структуры на основе ролей с использованием наследования и NHibernate.NHibernate Одиночное наследование таблицы

В принципе, я хотел бы иметь абстрактный класс под названием ObjectInRole. Этот класс (и соответствующая таблица базы данных) содержит RoleId, ObjectId и ObjectType (это будет столбец дискриминатора). Столбец дискриминатора будет типом объекта, который получает роль.

Для простоты предположим, что существует объект User, который содержит список (мешок) ролей. Я бы хотел, чтобы у меня был класс 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 для сохранения, когда я добавляю новую роль в коллекцию для объекта User. Он сохраняет новую запись в таблице ObjectToRole, но ObjectType имеет значение NULL. Посмотрев на сумку, он не загрузил это в коллекцию. Я думаю, что я сузил его до неправильной установки подкласса или неправильно установил пакет. Я склоняюсь к сумке, поскольку, по-моему, это просто обработка коллекции как куча абстрактного класса, а не подкласса UserInRole.

Просьба представить свои мысли по любым вопросам. Благодаря!

EDIT:

Таким образом, вместо того, чтобы пытаться добавить в мешок (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. Идентификатор является полем идентификатора и указан как таковой. Я полностью потеряю.

ответ

2

OK! После многократного воспроизведения файлов сопоставления я обнаружил недокументированную проблему (по крайней мере, я не мог найти упоминания об ошибке, которую я совершал).

При использовании подкласса родительский класс не может содержать сопоставление для свойства, являющегося столбцом дискриминатора. Если вы посмотрите на второй документ сопоставления, который я разместил, он показывает суперкласс и подкласс. Классификатором суперкласса является столбец ObjectType. Я также сопоставляю это как свойство абстрактного класса ObjectInRole. Ты не сможешь это сделать. Как только эта строка была удалена, все работает правильно (не сохраняя сумку).

Сумка кажется проблемой, которая не контролируется ничем, что я нашел в документации. Я не могу найти другой экземпляр, где абстрактный класс сохраняется через отображение. Похоже, что NHibernate не знает, что класс связывания является объектом UserInRole, а не объектом ObjectInRole. Изучая все параметры, которые предоставляются для узла сумки, не было никакого очевидного способа сообщить NHibernate, какой тип класса он связывал, чтобы сделать связь «многие-ко-многим». Из того, что я могу сказать, все равно, но более или менее рассматривает таблицу как таблицу, а не сопоставленный объект. Если бы можно было сказать, что он добавляет что-то для вставки, возможно, это будет возможно, но я не видел никакой информации об этом.

Смежные вопросы