2

パフォーマンス上の理由から、休止状態の多くの値型セットを 1 つのテーブルにマップしようとしています。最初に、それらすべてを独自のテーブルに配置したため、結合が多すぎました。

セットの束を持つ多くのコンポーネントを含む Categories クラスがあり、エンティティ名と識別子を使用して、サブクラスを介してそれらを単一のテーブルにマップします。マッピング スニペットについては、以下を参照してください。

これは問題なく機能しますが、すべてのセットを含む単一のテーブルであるため、コンポーネントが削除されたときにセットを自動的に削除することは困難です。これは、エンティティとしてモデル化されており、Hibernate がセットが削除されたことを通知できないためです。

マッピングの詳細:

<class name="com.sample.CategoriesDefault" table="dec_cats" >
 <id name="id" column="id" type="string" length="40" access="property">
  <generator class="assigned" />
 </id>
 <component name="incomeInfoMember" class="com.sample.IncomeInfoDefault">
   <property name="hasWage" type="boolean" column="inMemWage"/>
    ...
   <component name="wage" class="com.sample.impl.WageDefault">
     <property name="hasEmployerWage" type="boolean" column="inMemEmpWage"/>
      ...
     <set name="employerWages" cascade="all-delete-orphan" lazy="false">
      <key column="idCats" not-null="true" />
      <one-to-many entity-name="mIWaEmp"/>
     </set>
   </component>
 </component>
</class>

<class name="com.sample.NameValueTypeEntityMarker" table="cats_name_amount">
 <id name="id" column="id" type="string" length="40" access="property">
  <generator class="assigned" />
 </id>
 <discriminator type="string" force="true">
   <column name="objType" index="ixDiscrCatsNameAmt" length="25" not-null="true" />
 </discriminator>
 <version name="version" column="objVrs"  unsaved-value="negative"/>

 <property name="name" type="string" column="name" not-null="true" />
 <subclass name="com.sample.NameAmountsIntValueTypeEntityMarker">
  <property name="amount1" type="integer" column="amount1" access="property" not-null="true"/>
   ...
   <subclass entity-name="mIWaEmp" name="com.sample.EmployerWageDefault" discriminator-value="mIWaEmp" />
   <subclass entity-name="pIWaEmp" name="com.sample.impl.EmployerWageDefault" discriminator-value="pIWaEmp" />
 </subclass>
</class>

使用法:

Categories cats = new CategoriesDefault();
Wage wage = new Wage();
Set<EmployerWage> set = new HashSet<EmployerWage>();
set.add(new EmployerWageDefault(cats));
wage.setEmployerWages(set);
IncomeMember inc = new IncomeMemberDefault();
inc.setWage(wage);
cats.setIncomeMember(inc);
cats.saveOrUpdate(); // will store it in the db.

// now remove the income:
cats.setIncomeMember(null);
cats.saveOrUpdate();
cats = getPersister().findCats(cats.getId());
// ERROR: cats still contains IncomeMember, Wage and EmployerWages.

このエラーは、EmployerWages がカテゴリの子としてマークされているため (キー列を参照)、自動的に削除されないために発生します。そのため、コンポーネントが削除されたときではなく、カテゴリが削除されたときに孤児として削除されます...ただし、私はWageはコンポーネントであり、Hibernateの苦情があるため、EmployerWagesをWageの子にすることはできません...

Pffff...これを解決するのは非常に難しいです。アイデアは大歓迎です...

4

1 に答える 1

0

これが役立つかどうかはわかりませんが、テーブル内のさまざまな基準に基づいてロードする値の型を Hibernate に伝えるために、識別子列を使用してみましたか?

http://docs.jboss.org/hibernate/orm/3.3/reference/en-US/html/mapping.html#mapping-declaration-discriminator

于 2013-04-17T02:59:34.530 に答える