JPA @Embeddedおよび@Embeddable

1. 概要

このチュートリアルでは、埋め込みプロパティを含む1つのエンティティを単一のデータベーステーブルにマップする方法を説明します。
そのため、この目的のために、https://www.baeldung.com/jpa-hibernate-difference [Java Persistence API(JPA)]によって提供される_ @ Embeddable_および_ @ Embedded_注釈を使用します。

2. データモデルコンテキスト

まず、_company_というテーブルを定義しましょう。
_company_テーブルには、会社名、住所、電話などの基本情報と、連絡先の情報が格納されます。
public class Company {

    private Integer id;

    private String name;

    private String address;

    private String phone;

    private String contactFirstName;

    private String contactLastName;

    private String contactPhone;

    // standard getters, setters
}
*ただし、担当者は別のクラスに抽象化する必要があるようです。*問題は、*それらの詳細のために別のテーブルを作成したくないことです*。

3. _ @ Embeddable_

  • JPAは_ @ Embedded_アノテーションを提供して、クラスが他のエンティティによって埋め込まれることを宣言します。*

    連絡先の詳細を抽象化するクラスを定義しましょう:
@Embeddable
public class ContactPerson {

    private String firstName;

    private String lastName;

    private String phone;

    // standard getters, setters
}

4. @埋め込み

  • JPA注釈_ @ Embedded_は、型を別のエンティティに埋め込むために使用されます。*

    次に、_Company_クラスを変更しましょう。 JPAアノテーションを追加し、個別のフィールドの代わりに_ContactPerson_を使用するように変更します。
@Entity
public class Company {

    @Id
    @GeneratedValue
    private Integer id;

    private String name;

    private String address;

    private String phone;

    @Embedded
    private ContactPerson contactPerson;

    // standard getters, setters
}
その結果、エンティティ_Company_があり、連絡先の詳細を埋め込み、単一のデータベーステーブルにマッピングします。
ただし、もう1つ問題があります。それは* JPAがこれらのフィールドをデータベース列にマップする方法です*。

5. 属性のオーバーライド

問題は、元の_Company_クラスでは_contactFirstName_のようにフィールドが呼び出され、__ContactPerson __classでは_firstName_のようになったということです。 そのため、JPAはこれらをそれぞれ__contact_first_name ___と_first_name、_にマッピングします。
理想的ではないことは別として、複製された_phone_列で実際に私たちを壊してしまいます。
*したがって、_ @ AttributeOverrides_および_ @ AttibuteOverride_を使用して、埋め込み型の列プロパティをオーバーライドできます。*
これを__Company __entityの__ContactPerson __フィールドに追加しましょう:
@Embedded
@AttributeOverrides({
  @AttributeOverride( name = "firstName", column = @Column(name = "contact_first_name")),
  @AttributeOverride( name = "lastName", column = @Column(name = "contact_last_name")),
  @AttributeOverride( name = "phone", column = @Column(name = "contact_phone"))
})
private ContactPerson contactPerson;
これらの注釈はフィールドに適用されるため、囲むエンティティごとに異なるオーバーライドを設定できることに注意してください。

6. 結論

このチュートリアルでは、いくつかの埋め込み属性を持つエンティティを構成し、それらを囲むエンティティと同じデータベーステーブルにマップしました。 そのために、Java Persistence APIが提供する_ @ Embedded _、_ @ Embeddable _、_ @ AttributeOverrides_および_ @ AttributeOverride_注釈を使用しました。
いつものように、例のソースコードはhttps://github.com/eugenp/tutorials/tree/master/persistence-modules/spring-data-jpa-2[over GitHub]で入手できます。