ファイヤープロジェクト
多対1関連(Hibernate3)
2005-04-06T23:30+09:00   matsu
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);
これを逆にすると以下のような例外が発生した.
matsu(C)
Since 2002
Mail to matsu