ファイヤープロジェクト
複合キー(Hibernate3)
2005-04-17T20:10+09:00   matsu
複合キーのマッピングと,複合キーを外部キーにもつ場合のマッピング方法を調査してみた.
本頁のサンプルでは,以下のテーブルを扱う.
テーブルDetailは複合キー{ID,REGIST_DATE}をもつ. うちIDはテーブルOutlineを参照する外部キーである. テーブルMoreDetailは複合キー{ID,REGIST_DATE,SEQ_NO}をもつ. うち{ID,REGIST_DATE}はテーブルDetailを参照する外部キーである.
Detail(ID, REGIST_DATE)
MoreDetail(ID, REGIST_DATE, SEQ_NO,VALUE)
この二つのテーブルをそれぞれオブジェクトにマッピングする.
複合キーをもつテーブルDetailのマッピングファイルを以下にしめす.
複合キーの場合は,要素composite-idを使用する. 子要素はkey-many-to-oneか,key-propertyで,複合キーを構成する各要素を記述する. 両者の違いは,前者はさらに外部キーである場合,後者はそうでない場合に使用する. テーブルDetailの属性IDはテーブルOutlineのIDを参照するので,要素key-many-to-oneである.
<key-many-to-one name="outline" class="Outline" column="ID"/>
要素many-to-oneと同じ要領である. テーブルDetailの属性registDateは属性IDとともにテーブルDetailの主キーを構成する.
<key-property name="registDate" column="REGIST_DATE" type="date"/>
要素propertyと同じ要領である. 複合キーを使用する場合のhbmファイルの作成の要点は以上であるが,複合キーを使用する場合は,マッピングするクラスが以下の要件つく.
  • java.io.Serializableを継承する.
  • equalsメソッドを実装する.
  • hashCodeメソッドを実装する.
これを踏まえると,Detail.javaは以下のようになる(※).
今回は,主キーを構成しているOutline.id値とregistDateのミリ秒値にてhashCodeを生成し,それを使用してequalsメソッドを実装した.
※ equalsメソッドは以下の要件を満たす必要がある.
反射律
(a.equals(a) == true)
対象律
(a.equals(b) == true) → (b.equals(a) == true)
推移律
(a.equals(b) == true) & (b.equals(c) == true) → (a.equals(c) == true)
hashCodeメソッドの返り値は以下の要件を満たしている必要がある.
equalsがtrueの場合,必ずhashCode()の値は同じ(逆は成立するとは限らない).
(a.equals(b) == true) → (a.hashCode() == b.hashCode())
対象オブジェクトが同じ状態なら(メンバの値に変化がないなら)何度やっても返り値は同じ.
a.hashCode() == a.hashCode())
Detailは複合キーの一部IDがOutlineを参照していた. サンプルのもう一つのテーブルMoreDetailの複合キーはDetailのキー,すなわち上記のIDとregistDateを外部キーとしてもつ. さらにseqNoも複合キーを構成する. マッピングファイルは以下となる.
複合キーは要素composit-idであることはDetailと同じである. その子要素の外部キーがさらに複合キーの場合,要素key-meny-to-oneは子要素columnをもつ.
<key-many-to-one name="detail" class="Detail">
  <column name="ID"/>
  <column name="REGIST_DATE"/>
</key-many-to-one>
これで,属性ID,REGIST_DATEはテーブルDetailを参照すると表現された. キーでなく,通常の複合外部キーの場合も同様である. 上記が主キーの一部でなかった場合,以下のようになる.
<many-to-one name="detail" class="Detail">
  <column name="ID"/>
  <column name="REGIST_DATE"/>
</many-to-one>
MoreDetailも主キーが複合キーなので,Detailと同様,Serializableの継承,hashCode,equalsメソッドを実装する必要がある.
matsu(C)
Since 2002
Mail to matsu