継承 その2(Hibernate3)
一つのテーブルから,親クラス,子クラスへとマッピングするパターンを調査してみた.
本頁のサンプルでは,以下のテーブルを扱う.
下図のように,テーブルはSuperClassだけである.
親クラスSuperClass用の列,子クラスSub1,Sub2それぞれのための列がある.
そして各行がSuperClass,Sub1,Sub2のいずれにマッピングするものなのかを示す列TYPEがある.
このTYPEのような列をhibernateではDISCRIMINATORとよび,マッピング時には同名の要素を使用する.
クラス図は前頁と同じとなる.
サンプルでは一つのテーブルが一つの親クラスと二つの子クラスにマッピングされる.
hibernateは列DISCRIMINATORの値に応じて,どのクラスにマッピングするのかを判断する.
マッピングファイルは以下となる.
ポイントは三つ.
- クラスの親子関係は親クラスにあたる要素classの子要素に子クラスsubclassを記述する.
- 各要素class,subclassの属性discriminator-valueにDISCRIMINATORの値を記述する.
- 要素classにDISCRIMINATORとする列を指定する.
サンプルプログラムSuperSub.javaはテーブルが一つしかないので,最後の削除処理を若干修正したが,それ以外は前頁のものとほぼ同じである.
以下はsuperClassインスタンスをロードする際のSQLである.
select superclass0_.ID as ID, superclass0_.SUPERCLASS_VALUE as SUPERCLASS3_0_, superclass0_.SUB1_VALUE as SUB4_0_, superclass0_.SUB2_VALUE as SUB5_0_, superclass0_.TYPE as TYPE from SuperClass superclass0_テーブルSuperClassから全レコード,全列を取り出して,TYPEの値に応じて適切なSuperClass,あるいはそのサブクラスとしてインスタンス化してくれる. 続いて子クラスのSub1をロードする際のSQL.
select sub1x0_.ID as ID, sub1x0_.SUPERCLASS_VALUE as SUPERCLASS3_0_, sub1x0_.SUB1_VALUE as SUB4_0_ from SuperClass sub1x0_ where sub1x0_.TYPE='SUB1'次はTYPEの値がSub1に対応する'SUB1'のレコードのみを取り出す. クラスSub1にはマッピングされないSUB2_VALUEは選択リストにはない.

