イベントのコレクションを Person クラスに追加します。こうしておくと、明示的なクエリ、つまりわざわざ aPerson.getEvents() を呼び出さずに、特定の人に紐付くイベントを簡単にナビゲートすることができます。私たちは Java のコレクション、Set を使います。コレクションは重複要素を持たないし、順番は私たちには意味がないからです。
Set で実装される単方向、多値関連が必要です。 Java クラス内に対応するコードを書いてマッピングしましょう:
public class Person {
private Set events = new HashSet();
public Set getEvents() {
return events;
}
public void setEvents(Set events) {
this.events = events;
}
}
この関連をマッピングする前に、反対側について考えてください。明らかなことですが、今はこれを単方向にしただけです。逆に、 Event 側にも別のコレクションを作ることもできます。例えば anEvent.getParticipants() のように、双方向にナビゲートしたければ、そうすることもできます。これは機能的にみて必要ではありません。特定のイベントに関係するデータを取得する明確なクエリを、いつでも実行することが出来ました。この設計の選択は開発者に任されていて、この議論により明らかなのは関連の多重度です。つまり両側を「多」値にする、 多対多 と呼ばれる関連です。そのため Hibernate の多対多マッピングを使います:
<class name="events.Person" table="PERSON">
<id name="id" column="PERSON_ID">
<generator class="native"/>
</id>
<property name="age"/>
<property name="firstname"/>
<property name="lastname"/>
<set name="events" table="PERSON_EVENT">
<key column="PERSON_ID"/>
<many-to-many column="EVENT_ID" class="events.Event"/>
</set>
</class>
Hibernate はありとあらゆる種類のコレクションマッピングをサポートしていますが、最も一般的なものが <set> です。 多対多関連(または n:m エンティティリレーションシップ)には、関連テーブルが必要です。このテーブルのそれぞれの行は、人とイベント間のリンクを表現します。テーブル名は set 要素の table 属性で設定します。人側の関連の識別子カラム名は <key> 要素で、イベント側のカラム名は <many-to-many> の column 属性で定義します。 Hibernate にコレクションのオブジェクトのクラス (正確には、参照のコレクションの反対側のクラス)を教えなければなりません。
そのためこのマッピングのデータベーススキーマは以下のようになります:
_____________ __________________
| | | | _____________
| EVENTS | | PERSON_EVENT | | |
|_____________| |__________________| | PERSON |
| | | | |_____________|
| *EVENT_ID | <--> | *EVENT_ID | | |
| EVENT_DATE | | *PERSON_ID | <--> | *PERSON_ID |
| TITLE | |__________________| | AGE |
|_____________| | FIRSTNAME |
| LASTNAME |
|_____________|