Red Hat Training

A Red Hat training course is available for Red Hat JBoss Web Server

2.2.4. 値のコレクション

電子メールアドレスのコレクションを Person エンティティに追加してみましょう。これは、 java.lang.String インスタンスの java.util.Set として表されます。
    private Set emailAddresses = new HashSet();

    public Set getEmailAddresses() {
        return emailAddresses;
    }

    public void setEmailAddresses(Set emailAddresses) {
        this.emailAddresses = emailAddresses;
    }
Set のマッピングは次の通りです。
        <set name="emailAddresses" table="PERSON_EMAIL_ADDR">
            <key column="PERSON_ID"/>
            <element type="string" column="EMAIL_ADDR"/>
        </set>
以前のマッピングと比較して異なる点は、 element 部分の使い方です。 element の部分は、 コレクションに他のエンティティへの参照が含まれず、 要素が値型のコレクション (この例では string 型) であることを Hibernate に伝えます。 名前が小文字の場合、 Hibernate マッピング型かコンバーターであることが分かります。 ここでも、 set 要素の table 属性がコレクションのテーブル名を決定します。 key 要素はコレクションテーブルの外部キー列名を定義します。 element 要素の column 属性は、 電子メールアドレスの値が実際に保存される列名を定義します。
更新されたスキーマは次の通りです。
  _____________        __________________
 |             |      |                  |       _____________
 |   EVENTS    |      |   PERSON_EVENT   |      |             |       ___________________
 |_____________|      |__________________|      |    PERSON   |      |                   |
 |             |      |                  |      |_____________|      | PERSON_EMAIL_ADDR |
 | *EVENT_ID   | <--> | *EVENT_ID        |      |             |      |___________________|
 |  EVENT_DATE |      | *PERSON_ID       | <--> | *PERSON_ID  | <--> |  *PERSON_ID       |
 |  TITLE      |      |__________________|      |  AGE        |      |  *EMAIL_ADDR      |
 |_____________|                                |  FIRSTNAME  |      |___________________|
                                                |  LASTNAME   |
                                                |_____________|
コレクションテーブルの主キーは、 両列を使った複合キーであることが分かります。 これは、 人物ごとに電子メールアドレスを重複できないことを意味し、 Java のセットに要求されるセマンティックとなります。
人物とイベントをリンクした時のように、 このコレクションに要素を追加してみましょう。 Java の同じコードになります。
    private void addEmailToPerson(Long personId, String emailAddress) {
        Session session = HibernateUtil.getSessionFactory().getCurrentSession();
        session.beginTransaction();

        Person aPerson = (Person) session.load(Person.class, personId);
        // adding to the emailAddress collection might trigger a lazy load of the collection
        aPerson.getEmailAddresses().add(emailAddress);

        session.getTransaction().commit();
    }
今回は、 fetch クエリを使用してコレクションを初期化しませんでした。 SQL ログを監視し、 eager フェッチで最適化してみます。