1.3.2. 単方向 Set ベース関連

1.3.2. 単方向 Set ベース関連

イベントのコレクションを 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   |
                                                  |_____________|