0

複合キーを持ち、完全に機能しているクラス StoreHours があります。別のタイプの時間を返してほしいという新たな要求が出てきました。私は「単純です。基本クラスを抽象化し、2 つの具体的な実装を用意して、アプリ内の参照を新しいクラスの 1 つに変更します」と考えました。ただし、それを行うと、単体テストは失敗しました

X.Test.StoreTest.HoursTest: NHibernate.InstantiationException: 抽象クラスまたはインターフェースをインスタンス化できません: X.Model.StoreHours

私のマッピングファイルは次のようになります

<class name="StoreHours" table="StoreHour" abstract="true" discriminator-value="0" >
    <composite-id>
        <key-many-to-one name="Store"
            class="Store"
            column="StoreUid"/>
        <key-property name="DayOfWeek" 
            column="DayOfWeekId"
            type="System.DayOfWeek" />
    </composite-id>
    <discriminator column="StoreHourType" type="Byte" />
    <property name="OpenMinutes" column="OpenTime" />
    <property name="CloseMinutes" column="CloseTime" />
    <subclass name="OfficeHours" discriminator-value="1" />
    <subclass name="AccessHours" discriminator-value="2" />
</class>

ここで同様の問題を抱えている人を見つけて、彼らの解決策をたどり始めましたが、実際には、最初よりもさらに多くの問題が発生しました。

レコードをデータベースに完全に永続化できますが、オンロードすると、「OfficeHours」から強力な型セットしか取得していないにもかかわらず、NHibernate は抽象的な「StoreHours」をインスタンス化しようとしています。

これは本当に些細な要件のように思えるので、何か単純な間違いをしているに違いないと思います。すべてのヒントに感謝します。

4

1 に答える 1

1

The problem is in the way you are using the composite-id

Table-per-class works with Composite-id, but only if the composite is implemented as a class

so you need to create a class like

public class StoreHoursCompositeId
 {
        public virtual Store Store { get; set; }
        public virtual DayOfWeek DayOfWeek { get; set; }

        // Implement GetHashCode(), is NH-mandatory
        // Implement Equals(object obj), is NH-mandatory
}

In your StoreHours object create a property which use the above class (in my example I called it "StoreHoursCompositeId")

Your mapping become:

<class name="StoreHours" table="StoreHour" abstract="true" discriminator-value="0" >
    <composite-id name="StoreHoursCompositeId" class="StoreHoursCompositeId">
        <key-many-to-one name="Store" class="Store"
            column="StoreUid"/>
        <key-property name="DayOfWeek" 
            column="DayOfWeekId"
            type="System.DayOfWeek" />
    </composite-id>
    <discriminator column="StoreHourType" type="Byte" />
    <property name="OpenMinutes" column="OpenTime" />
    <property name="CloseMinutes" column="CloseTime" />
    <subclass name="OfficeHours" discriminator-value="1" />
    <subclass name="AccessHours" discriminator-value="2" />
</class>

I had the very same problem and this fixed it for me.

于 2014-05-28T09:14:21.070 に答える