多対1関連(Hibernate3)
Hibernateを使用すると,多対1の関連も簡単に復元,保存などができる.
本頁のサンプルでは,以下のテーブルを扱う.
テーブル名通り,OneSideが1側,ManySideが多側である.
ManySideが外部キーとしてOneSideのIDをもつ.
OneSideに対応するJavaファイル,マッピングファイルは前頁のSimpleMessageと同様である.
ManySideは以下に示す.
多側であるManySideのオブジェクトは,外部キー経由で1件のOneSideと結びつけられる.
したがって,ManySideにはメンバとしてoneSideがあり,それ用のsetterとgetterがある.
ManySideのマッピングファイルは以下となる.
ポイントは要素many-to-oneである.
多側(外部キーをもつ側)のマッピングファイルに(1側の)フィールド名,(1側の)クラス名,(ManySideにおける)外部キーの属性名を記述する.
<many-to-one name="oneSide" class="OneSide" column="ONE_SIDE_ID"/>ManySide.javaではフィールドoneSideがあって,ONE_SIDE_IDの扱いは全てHibernateが請け負ってくれる点が嬉しい.
サンプルでは,ManyToOne.javaにて上記でマッピングしたオブジェクトを扱う.
OneSideの作成とDB保存は前頁のSimpleMessageと同様である.
ManySideについても同様に,「普通の」Javaプログラミングを行って,Session#save(Object)を呼び出せばよい.
ManySide manySide = new ManySide(); // ManySideオブジェクトのメンバとしてOneSideのオブジェクトをsetする. // SQL発行時にはONESIDEテーブルのID属性を参照するMANYSIDEテーブルのONE_SIDE_IDが設定される. manySide.setOneSide(oneSide); manySide.setValue(i); // DBに格納 session.save(manySide);manySide.setOneSideで,1側のオブジェクトと多側のオブジェクトが(Javaプログラム的に)関連づけられる. そしてsession.save(manySide)によって,Hibernateが上記関連を反映したSQLを自動生成し,DBにおいても上記関連が維持される. サンプルの場合だと,oneSideは既に別メソッドによってDB上にあるので,oneSideのフィールドid値をManySideのONE_SIDE_IDの値として指定するSQLが生成される.
サンプルのメソッドloadManySidesはDBからManySide,OneSideの構造を意識した読み込みをする.
Hibernateのログを見ると以下のようになっている.
OneSide,ManySideそれぞれのオブジェクトを必要最小限の数復元し,両者を適切に関連づける作業までをHibernateがやってくれているのが分かる.
サンプルではcascade指定していないので,1側を消すには,1側であるOneSideを参照している多側であるManySideをDB上から削除してからOneSideを削除する必要がある.
以下は該当箇所mainメソッドの末尾.
// Cascadeしていないので,先に参照側を削除しておく必要がある. deleteAllManySide(sessionFactory); deleteOneSide(sessionFactory, oneSideList); manySideList = loadManySides(sessionFactory);これを逆にすると以下のような例外が発生した.

