1. 序章

このチュートリアルでは、複合主キーとそれに対応するJPAの注釈について学習します。

2. 複合主キー

複合主キーは、複合キーとも呼ばれ、テーブルの主キーを形成するための2つ以上の列の組み合わせです。

JPAでは、複合キーを定義するための2つのオプションがあります。@IdClassおよび@EmbeddedIdアノテーションです。

複合主キーを定義するには、いくつかのルールに従う必要があります。

  • 複合主キークラスはパブリックである必要があります。
  • 引数なしのコンストラクターが必要です。
  • equals()および hashCode()メソッドを定義する必要があります。
  • S erializableである必要があります。

3. IdClassアノテーション

Account というテーブルがあり、複合キーを形成する accountNumberaccountType、の2つの列があるとします。 次に、JPAでマップする必要があります。

JPA仕様に従って、次の主キーフィールドを使用してAccountIdクラスを作成しましょう。

public class AccountId implements Serializable {
    private String accountNumber;

    private String accountType;

    // default constructor

    public AccountId(String accountNumber, String accountType) {
        this.accountNumber = accountNumber;
        this.accountType = accountType;
    }

    // equals() and hashCode()
}

次に、AccountIdクラスをエンティティAccountに関連付けましょう。

そのためには、エンティティに@IdClassアノテーションを付ける必要があります。 また、エンティティAccountAccountIdクラスのフィールドを宣言し、@Idで注釈を付ける必要があります。

@Entity
@IdClass(AccountId.class)
public class Account {
    @Id
    private String accountNumber;

    @Id
    private String accountType;

    // other fields, getters and setters
}

4. EmbeddedIdアノテーション

@EmbeddedId は、@IdClassアノテーションの代替です。

タイトル言語を主キーフィールドとして、Bookの情報を保持する必要がある別の例を考えてみましょう。

この場合、主キークラス BookIdには、@Embeddableという注釈を付ける必要があります。

@Embeddable
public class BookId implements Serializable {
    private String title;
    private String language;

    // default constructor

    public BookId(String title, String language) {
        this.title = title;
        this.language = language;
    }

    // getters, equals() and hashCode() methods
}

次に、 @EmbeddedId を使用して、このクラスを B ookエンティティに埋め込む必要があります。

@Entity
public class Book {
    @EmbeddedId
    private BookId bookId;

    // constructors, other fields, getters and setters
}

5. @IdClass@EmbeddedId

ご覧のとおり、これら2つの表面の違いは、 @IdClass では、 AccountIdAccountの2回列を指定する必要があることです。 ただし、@EmbeddedIdでは使用しませんでした。

ただし、他にもいくつかのトレードオフがあります。

たとえば、これらのさまざまな構造は、作成するJPQLクエリに影響を与えます。

@IdClass を使用すると、クエリが少し簡単になります。

SELECT account.accountNumber FROM Account account

@EmbeddedId を使用して、追加のトラバーサルを1つ実行する必要があります。

SELECT book.bookId.title FROM Book book

また、 @IdClassは、が変更できない複合キークラスを使用している場所で非常に役立ちます。

複合キーの一部に個別にアクセスする場合は、 @ IdClass、を使用できますが、完全な識別子をオブジェクトとして頻繁に使用する場所では、@EmbeddedIdが推奨されます。

6. 結論

この短い記事では、JPAの複合主キーについて説明しました。

いつものように、この記事の完全なコードはGithubで見つけることができます。