継承 その1(Hibernate3)
クラスの継承関係とテーブルのマッピングのうち,今回は親クラス,子クラスそれぞれに対応するテーブルがあるパターンを調査してみた.
本頁のサンプルでは,以下のテーブルを扱う.
下図のように,親テーブルSuperClassを,子テーブルSub1,Sub2が継承している.
親子のテーブルは属性IDで関連づけられる.
すなわちSub1,Sub2のIDはSuperClass.IDを参照する外部キーである.
オブジェクトの世界での継承関係は,下図のように関連と同様になる.
サンプルでは三つのテーブルが一つの親クラスと二つの子クラスにマッピングされる.
マッピングファイルは以下となる.
ポイントとなる要素はjoined-subclassである.
名前の通り,子クラスをテーブルからインスタンス化するSQLは,親テーブルと子テーブルのjoinによって行われる.
SELECT * FROM 子 inner join 親 on キー;「子」は要素joined-subclassで指定されたテーブルで,「親」はその要素joined-subclassの親要素で指定されたテーブルである. 要素joined-subclassは子要素keyを持ち,これが「キー」となる. 下は子要素のマッピング記述である.
<joined-subclass name="Sub1" table="Sub1"> <key column="ID"/> <property name="sub1Value" column="SUB1_VALUE" type="int"/> </joined-subclass>サンプルを実行してみると,Sub1のロード時には以下のようなSQLが発行されることがわかる.
select sub1x0_.ID as ID, sub1x0_1_.SUPERCLASS_VALUE as SUPERCLASS2_0_,
sub1x0_.SUB1_VALUE as SUB2_1_
from Sub1 sub1x0_ inner
join SuperClass sub1x0_1_
on sub1x0_.ID=sub1x0_1_.ID
サンプルプログラムSuperSub.javaには以下の記述がある.
Query query = session.createQuery("delete from Sub1");
int result = query.executeUpdate();
サブクラスの全レコードを削除するコードであるが,実行すると例外となる.
Exception in thread "main" org.hibernate.QueryException: Delete statements against joined or union subclasses not yet supported! [delete from org.fireproject.hibernatesample.Sub1]わりと困る.

