Hibernate で次のクラス階層をマッピングするために、「階層ごとのクラス戦略」を使用しました。
私はアイテムを抽象クラスとして持っています。具体的なものとしては以下のよう なものです 。
私のマッピングは保存と読み込みには完璧に機能しますが、別のクラスでアイテムを更新すると正しく機能しません。上記の各クラスに識別子を使用しています。
私のitem.hbm.xmlは次のようなものです:
<!-- language: lang-xml -->
<hibernate-mapping>
<class name="my.hibernate.items.Item" discriminator-value="item"
table="testitem" catalog="efeu">
<id name="id" type="java.lang.Long">
<column name="id" />
<generator class="native" />
</id>
<discriminator column="item_type" type="string" length="8" />
<subclass name="my.hibernate.items.DVD" discriminator-value="DVD">
<property name="duration" type="java.lang.Integer" column="duration" />
<property name="trackNumber" type="java.lang.Integer"
column="trackNumber" />
</subclass>
<subclass name="my.hibernate.items.Journal"
discriminator-value="Journal">
<property name="serialNumber" type="java.lang.Integer"
column="serial_number" />
</subclass>
</class>
</hibernate-mapping>
更新には、次の方法を使用します。
<!-- language: lang-java -->
public static void updateItem(Item newItem){
Session session = HibernateSessionFactory.getSession();
Transaction tx = session.beginTransaction();
session.update(newItem);// I tried merge too. it created a new row
tx.commit();
session.close();
}
updateItem メソッドに送信するクラス インスタンスに違いはありません。ディスクリミネーターを除くすべてのフィールドが更新されるため、本である場合は本のままであり、その種類のオブジェクトをパラメーターとして使用して上記のメソッドを呼び出して CD、DVD、またはジャーナルに変換することはできません。
私が何をしているのかは明らかだと思います。データベース テーブルの id=111 の行が Book オブジェクトであることはわかっていると思います。だから私は次のことをします:
<!-- language: lang-java -->
Item cd = new CD();
cd.setId(111);
cd.setXXXProperties()
Item.updateItem(cd);
メソッドを呼び出す前に cd が一時的であることは明らかであり、その前に id=111 の行をロードしていません。
update メソッドの呼び出し時に Hibernate に識別子列を変更させるにはどうすればよいですか?