2009-03-20 19 views
1

継承とNHibernateを使用してロールベースの構造を設定する際に問題があります。NHibernate単一テーブルの継承

基本的にObjectInRoleという抽象クラスが必要です。このクラス(および対応するデータベーステーブル)には、RoleId、ObjectId、およびObjectType(これが識別子カラムです)が含まれています。弁別子列は、役割を獲得するオブジェクト型です。

簡単にするために、ロールのリスト(バッグ)を含むUserオブジェクトがあるとします。 ObjectInRoleのサブクラスである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> 

:この設定を持つ

<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の代わりに抽象クラスの束としてコレクションを扱っているだけかもしれないと思うので、バッグの方に傾いています。

いずれかの地域にあなたの考えを示してください。ありがとう!

EDIT:

ので、代わりのバッグ(User.Roles.add(役割))に追加しようとすると、多対多のは私がちょうどまっすぐに追加することを決定したリンクオブジェクトを永続化するましたテーブルのオブジェクト。新しいエラーが発生しています:

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

上記のクラスを見ると、私はUserオブジェクトとRoleオブジェクトを設定しています。 idはIDフィールドであり、そのように指定されます。私は完全に迷っています。

答えて

2

OK!マッピングファイルを使って遊んだ後で、私は文書化されていない問題が見つかりました(少なくとも、私がコミットしていたエラーについては何の言及も見つけられませんでした)。

サブクラス化を使用する場合、親クラスには、識別子の列であるプロパティのマッピングを含めることはできません。投稿した2番目のマッピングドキュメントを見ると、スーパークラスとサブクラスが表示されます。スーパークラスの弁別子はObjectType列です。また、これを抽象クラスObjectInRoleにプロパティとしてマップします。あなたはこれをすることはできません。この行が削除されると、すべてが正しく機能しました(バッグを保管しない)。

バッグは、ドキュメントで見つけたものでは制御できない問題のようです。私は抽象クラスがマッピングを通じて保存されている場所の別のインスタンスを見つけることができません。 NHibernateは、リンククラスがObjectInRoleオブジェクトではなく、UserInRoleオブジェクトであることを知らないようです。バッグノードに提供されるすべてのオプションを調べることで、NHibernateに多対多関連を作るためにリンクしているクラスのタイプを伝える明白な方法はありませんでした。私が気にしていることから、それは気にしませんが、多かれ少なかれ、テーブルはマップされたオブジェクトではなく単なるテーブルとして扱われます。挿入のために何かを追加する方法があれば可能かもしれないが、これに関する情報は見ていない。

関連する問題