ファイヤープロジェクト
継承 その2(Hibernate3)
2005-04-24T14:10+09:00   matsu
一つのテーブルから,親クラス,子クラスへとマッピングするパターンを調査してみた.
本頁のサンプルでは,以下のテーブルを扱う.
下図のように,テーブルはSuperClassだけである.
親クラスSuperClass用の列,子クラスSub1,Sub2それぞれのための列がある. そして各行がSuperClass,Sub1,Sub2のいずれにマッピングするものなのかを示す列TYPEがある. このTYPEのような列をhibernateではDISCRIMINATORとよび,マッピング時には同名の要素を使用する. クラス図は前頁と同じとなる.
サンプルでは一つのテーブルが一つの親クラスと二つの子クラスにマッピングされる. hibernateは列DISCRIMINATORの値に応じて,どのクラスにマッピングするのかを判断する. マッピングファイルは以下となる.
ポイントは三つ.
  1. クラスの親子関係は親クラスにあたる要素classの子要素に子クラスsubclassを記述する.
  2. 各要素class,subclassの属性discriminator-valueにDISCRIMINATORの値を記述する.
  3. 要素classにDISCRIMINATORとする列を指定する.
サンプルではDISCRIMINATORとして列TYPEが指定されている. 列TYPEの値が'SUPE','SUB1','SUB2'なら,それぞれSuperClass,Sub1,Sub2にマッピングされる.
サンプルプログラム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は選択リストにはない.
matsu(C)
Since 2002
Mail to matsu