2.2.5.1. One-to-one 一対一

<2.2.5. Mapping entity bean associations/relationships | 目次 | 2.2.5.2. Many-to-one>

@OneToOne を使って、エンティティBeanに1対1関連を関連付けることができるよ。1対1関連は3つの方法があるよ。同じ主キーを共有する方法、一方のエンティティが外部キーを持つ方法(データベースの外部キーカラムはユニーク制約にしてないといけないよ)、二つのエンティティのリンクを持つ関連テーブル(それぞれの外部キーはユニーク制約にしないといけないよ)。

最初に、共有主キーを使った1対1関連だよ。

@Entity
public class Body {
    @Id
    public Long getId() { return id; }

    @OneToOne(cascade = CascadeType.ALL)
    @PrimaryKeyJoinColumn
    public Heart getHeart() {
        return heart;
    }
    ...
}
@Entity
public class Heart {
    @Id
    public Long getId() { ...}
}

@PrimaryKeyJoinColumn アノテーションを使って、1対1を有効にするよ。

次の例では、外部キーを使った関連だよ。

@Entity
public class Customer implements Serializable {
    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name="passport_fk")
    public Passport getPassport() {
        ...
    }

@Entity
public class Passport implements Serializable {
    @OneToOne(mappedBy = "passport")
    public Customer getOwner() {
    ...
}

Customer は、Customer テーブルの passport_fk という名前の外部キーを使って、Passsport と結びついてるよ。結合されるカラムは、@Column アノテーションみたいに、@JoinColumn アノテーションで定義されるよ。これは referencedColumnName といういくつかのパラメータを持つよ。このパラメータは結合される対象のエンティティのカラムを書くよ。referencedColumnName を主キーじゃないカラムに使うとき、関連するクラスは Serializable じゃないといけないから気をつけて。また、マッピングされるプロパティはシングルカラムじゃないといけないよ。

関連は双方向になるかもしれないね。双方向の場合、片側が親になって、親は関連するカラムの更新に責任を持つよ。関連の責任を持たない方には、 mappedBy 属性を使うよ。mappedBy は、親の関連するプロパティ名を参照するよ。この例では passport がそうだね。見ての通り、親のほうに書いているから、こっちには結合カラムを書かなくてよいよ。

親側に @JoinColumn が宣言されてないと、デフォルトが適応されるよ。結合カラムが親テーブルに作られて、親の関連名、_(アンダースコア)、主キー名を繋げた名前になるよ。この例では、プロパティ名が passport、Passport の 主キーが id なので、passport_id になるよ。

関連テーブルを使った3つ目の方法は、結構特殊だよ。

@Entity
public class Customer implements Serializable {
    @OneToOne(cascade = CascadeType.ALL)
    @JoinTable(name = "CustomerPassports",
        joinColumns = @JoinColumn(name="customer_fk"),
        inverseJoinColumns = @JoinColumn(name="passport_fk")
    )
    public Passport getPassport() {
        ...
    }

@Entity
public class Passport implements Serializable {
    @OneToOne(mappedBy = "passport")
    public Customer getOwner() {
    ...
}

Customer は CustomerPassports という名前の関連テーブルで、Passport と結びついているよ。この関連テーブルは Passport テーブルを指す passport_fk という外部キーカラム(inverseJoinColumnで書かれている)と、joinColumns で指定された Customer を指す customer_fk という 外部キーカラムを持つよ。

このマッピングでは、結合テーブル名と結合カラム目をはっきり書かないといけないよ。<2.2.5. Mapping entity bean associations/relationships | 目次 | 2.2.5.2. Many-to-one>