1. 概要

このチュートリアルでは、@AttributeOverrideを使用して列マッピングを変更する方法を示します。 エンティティを拡張または埋め込むときに使用する方法を説明し、単一およびコレクションの埋め込みについて説明します。

2. @AttributeOverrideの属性

注釈には、2つの必須属性が含まれています。

  • name –含まれるエンティティのフィールド名
  • column –元のオブジェクトで定義されたものをオーバーライドする列定義

3. @MappedSuperclassで使用

Vehicle class を定義しましょう

@MappedSuperclass
public class Vehicle {
    @Id
    @GeneratedValue
    private Integer id;
    private String identifier;
    private Integer numberOfWheels;
    
    // standard getters and setters
}

@MappedSuperclass アノテーションは、それが他のエンティティの基本クラスであることを示します。

次にクラスを定義しましょう 、拡張します車両。 エンティティを拡張し、車の情報を1つのテーブルに格納する方法を示します。 アノテーションはクラスにあることに注意してください。

@Entity
@AttributeOverride(name = "identifier", column = @Column(name = "VIN"))
public class Car extends Vehicle {
    private String model;
    private String name;

    // standard getters and setters
}

その結果、すべての車の詳細と車両の詳細を含む1つのテーブルが作成されます。 車の場合、識別子を列に格納する必要があります VIN。 私たちはそれを達成します @AttributeOverride。 注釈は、フィールド識別子がVIN列に格納されることを定義します。 

4. 埋め込みクラスで使用

次に、2つの埋め込み可能なクラスを使用して、車両に詳細を追加しましょう。

まず、基本的な住所情報を定義しましょう。

@Embeddable
public class Address {
    private String name;
    private String city;

    // standard getters and setters
}

また、自動車メーカーの情報を使用してクラスを作成しましょう。

@Embeddable
public class Brand {
    private String name;
    private LocalDate foundationDate;
    @Embedded
    private Address address;

    // standard getters and setters
}

ブランドクラスには、アドレスの詳細を含む埋め込みクラスが含まれています。 これを使用して、複数レベルの埋め込みで@AttributeOverrideを使用する方法を示します。

ブランドの詳細で拡張しましょう。

@Entity
@AttributeOverride(name = "identifier", column = @Column(name = "VIN"))
public class Car extends Vehicle {
    // existing fields

    @Embedded
    @AttributeOverrides({
      @AttributeOverride(name = "name", column = @Column(name = "BRAND_NAME", length = 5)),
      @AttributeOverride(name = "address.name", column = @Column(name = "ADDRESS_NAME"))
    })
    private Brand brand;

    // standard getters and setters
}

まず、 @AttributeOverridesアノテーションを使用すると、複数の属性を変更できます。 Car クラスに同じ列が存在するため、Brandクラスのname列の定義をオーバーライドしました。 その結果、ブランド名は列BRAND_NAMEに格納されます。

さらに、列の長さを定義して、列名だけでなくオーバーライドできることを示しています column属性は、オーバーライドされたクラスのすべての値をオーバーライドすることに注意してください。 元の値を維持するには、すべてをに設定する必要があります属性

これに加えて、Addressクラスのname列がADDRESS_NAMEにマップされています。 複数レベルの埋め込みでマッピングをオーバーライドするには、ドット「。」を使用します。 オーバーライドされたフィールドへのパスを指定します。

5. 埋め込みコレクション

この注釈を少し試して、コレクションでどのように機能するかを見てみましょう。

車の所有者の詳細を追加しましょう:

@Embeddable
public class Owner {
    private String name;
    private String surname;

    // standard getters and setters
}

住所と一緒に所有者が欲しいので、所有者とその住所の地図を追加しましょう

@Entity
@AttributeOverride(name = "identifier", column = @Column(name = "VIN"))
public class Car extends Vehicle {
    // existing fields

    @ElementCollection
    @AttributeOverrides({
      @AttributeOverride(name = "key.name", column = @Column(name = "OWNER_NAME")),
      @AttributeOverride(name = "key.surname", column = @Column(name = "OWNER_SURNAME")),
      @AttributeOverride(name = "value.name", column = @Column(name = "ADDRESS_NAME")),
    })
    Map<Owner, Address> owners;

    // standard getters and setters
}

アノテーションのおかげで、Addressクラスを再利用できます。 key プレフィックスは、Ownerクラスのフィールドのオーバーライドを示します。 さらに、 value プレフィックスは、Addressクラスのフィールドを指します。 リストの場合、追加のプレフィックスは必要ありません。

6. 結論

これで、@AttibuteOverrideアノテーションに関するこの短い記事は終わりです。 エンティティを拡張または埋め込むときにこのアノテーションを使用する方法を見てきました。 その後、コレクションでの使用方法を学びました。

いつものように、例のソースコードはGitHubから入手できます。