2

私たちはレガシーデータベースを使用していますが、Hibernate をそのまま使用してセットアップが可能かどうか疑問に思っています。

Entity と EntityDef の 2 つのテーブルがあります。

CREATE TABLE entity
( 
  id DOUBLE,
  name VARCHAR(20),
  PRIMARY KEY (id)
)

CREATE TABLE entitydef 
( 
  id DOUBLE,
  effectivedate DATE,
  terminationdate DATE,
  category VARCHAR(20),

  PRIMARY KEY (id, terminationdate)
)

基本的にすべてのエンティティに対して、特定の有効期間のパラメータを指定する複数の対応する EntityDef を持つことができます。これらの EntityDef の有効期間はばらばらであるため、任意の時点で Entity と EntityDef の間に 1 対 1 の関係が存在する必要があります。問題は、hibernate を使用してエンティティ テーブルをマップしようとしたときに発生します。次のマッピングを使用します

<class name="com.company.Entity" table="Entity">
    <cache usage="read-write" />
    <id name="id" type="long">
        <column name="id" />
    </id>
    <property name="name" type="string">
        <column name="name" />
    </property>
    <join table="entitydef">
        <key>
            <column name="id" sql-type="long />
        </key>
        <property name="category" type="string">
            <column name="category" />
        </property>
    </join>
</class>

<class name="com.company.EntityDef" table="entitydef">
    <cache usage="read-write" />
    <composite-id>
        <key-property name="id" type="long">
            <column name="id" />
        </key-property>
        <key-property name="terminationDate" type="com.company.time.hibernate.Date">
            <column name="terminationdate" />
        </key-property>
    </composite-id>
    <property name="category">
        <column name="category" />
    </property>
</class>

問題は、別の hibernate マッピングが複数の EntityDefs を持つエンティティをその ID のみで参照する場合に発生します。

...
<many-to-one name="entity" class="com.company.Entity" lazy="false">
    <column name="entityid" />
</many-to-one>
...

ID でエンティティの Hibernate クエリを実行し、意味のある例外をスローします。

org.hibernate.HibernateException: More than one row with the given identifier was found: 1, for class: com.company.Entity

Hibernate のドキュメントに示されているように、EntityDef マッピングにフィルターを追加してみました。

<filter-def name="effectiveDate">
    <filter-param name="asOfDate" type="date" />
</filter-def>   
<class name="com.company.EntityDef" table="entitydef">
    <cache usage="read-write" />
    <composite-id>
        <key-property name="id" type="long">
            <column name="id" />
        </key-property>
        <key-property name="terminationDate" type="com.company.time.hibernate.Date">
            <column name="terminationdate" />
        </key-property>
    </composite-id>
    <property name="category">
        <column name="category" />
    </property>
    <filter name="effectiveDate" condition=":asOfDate BETWEEN effectivedate and terminationdate" />
</class>

そして、次のコードをクエリに追加しました。

sess.enableFilter("effectiveDate").setParameter("asOfDate", new Date());

しかし、それは何も影響しなかったようです。

私の質問はこれです: このセットアップは可能ですか? また、終了日を明示的に指定せずに EntityDef テーブルに参加する方法はありますか? そうでない場合、最善の解決策は何ですか?1 対多の関係を作成し、Entity クラスでロジックを使用して、コレクションから正しい EntityDef をフェッチしますか?

カテゴリなどがエンティティの一部であることを期待する多くのビジネス ロジックがあるため、1 対多の関係に頼る必要がなければ、優れたものになります。

ありがとう!

4

1 に答える 1