Red Hat Training

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

第9章 コンポーネントのマッピング

コンポーネント の概念は、Hibernate 全体で様々な状況や目的に再利用されます。

9.1. 依存オブジェクト

コンポーネントは、エンティティの参照ではなく値型として永続化された、包含オブジェクトです。「コンポーネント」という言葉については、アーキテクチャレベルのコンポーネントではなく、コンポジションというオブジェクト指向の概念を参照してください。例えば、以下ように Personをモデル化できます。
public class Person {
    private java.util.Date birthday;
    private Name name;
    private String key;
    public String getKey() {
        return key;
    }
    private void setKey(String key) {
        this.key=key;
    }
    public java.util.Date getBirthday() {
        return birthday;
    }
    public void setBirthday(java.util.Date birthday) {
        this.birthday = birthday;
    }
    public Name getName() {
        return name;
    }
    public void setName(Name name) {
        this.name = name;
    }
    ......
    ......
}
public class Name {
    char initial;
    String first;
    String last;
    public String getFirst() {
        return first;
    }
    void setFirst(String first) {
        this.first = first;
    }
    public String getLast() {
        return last;
    }
    void setLast(String last) {
        this.last = last;
    }
    public char getInitial() {
        return initial;
    }
    void setInitial(char initial) {
        this.initial = initial;
    }
}
ここで NamePerson のコンポーネントとして永続化することが出来ます。Name は永続化プロパティに対して getter 、setter メソッドを定義しますが、インターフェースや識別子プロパティを宣言する必要はありません。
Hibernateマッピングは以下のようになります。
<class name="eg.Person" table="person">
    <id name="Key" column="pid" type="string">
        <generator class="uuid"/>
    </id>
    <property name="birthday" type="date"/>
    <component name="Name" class="eg.Name"> <!-- class attribute optional -->
        <property name="initial"/>
        <property name="first"/>
        <property name="last"/>
    </component>
</class>
Person テーブルは pidbirthdayinitialfirstlast カラムを持ちます。
値型のように、コンポーネントは参照の共有には対応していません。言い換えると、二人の Person は同じ名前を持つことができますが、二つの Person オブジェクトは値が「同じ」だけで別々の name オブジェクトを含んでいるということです。コンポーネントの null 値のセマンティクスは アドホック です。包含オブジェクトを再読み込みする際、Hibernate はコンポーネントのすべてのカラムが null であるならコンポーネント全体が null であると考えます。これは大抵の場合問題ありません。
コンポーネントのプロパティはどんな Hibernate の型でも構いません(コレクション、 many-to-one 関連、他のコンポーネントなど)。ネストされたコンポーネントは滅多に使わないと考えるべきでは ありません 。Hibernate は きめの細かいオブジェクトモデルをサポートするように意図されています。
<component> 要素は、親エンティティへ戻る参照として、コンポーネントのクラスのプロパティをマッピングする <parent> サブ要素を許可します。
<class name="eg.Person" table="person">
    <id name="Key" column="pid" type="string">
        <generator class="uuid"/>
    </id>
    <property name="birthday" type="date"/>
    <component name="Name" class="eg.Name" unique="true">
        <parent name="namedPerson"/> <!-- reference back to the Person -->
        <property name="initial"/>
        <property name="first"/>
        <property name="last"/>
    </component>
</class>