JPAの複合主キー
はじめに
このチュートリアルでは、複合主キーとJPAの対応する注釈について学びます。
複合主キー
複合主キー(複合キーとも呼ばれます)は、テーブルの主キーを形成するための2つ以上の列の組み合わせです。
JPAでは、複合キーを定義するための2つのオプションがあります:@IdClass注釈と@EmbeddedId注釈。
複合主キーを定義するには、いくつかのルールに従う必要があります:
- 複合主キークラスはpublicでなければなりません
- 引数なしのコンストラクタが必要です
- equals()メソッドとhashCode()メソッドを定義する必要があります
- 直列化可能でなければなりません
IdClassアノテーション
accountと呼ばれるテーブルには、複合キーを形成する2つの列AccountNumber、AccountTypeがあります。 今、私たちは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アノテーションをアノテーションする必要があります。 また、エンティティAccountのAccountIdクラスのフィールドを宣言し、@Idで注釈を付ける必要があります:
@Entity@IdClass(AccountId.class)public class Account { @Id private String accountNumber; @Id private String accountType; // other fields, getters and setters}
EmbeddedIdアノテーション
@EmbeddedIdは、@IdClassアノテーションの代わりになります。
主キーフィールドとしてタイトルと言語を持つ本の情報を保持する必要がある別の例を考えてみましょう。
この場合、主キークラスBookIdに@Embeddable注釈を付ける必要があります:
@Embeddablepublic 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を使用してこのクラスをBookエンティティに埋め込む必要があります:
@Entitypublic class Book { @EmbeddedId private BookId bookId; // constructors, other fields, getters and setters}
@IdClass対@EmbeddedId
先ほど見たように、これら2つの表面上の違いは、@IdClassでは、AccountIdに1回、Accountにもう一度列を指定する必要があったことです。 しかし、@EmbeddedIdではそうしませんでした。
ただし、他にもいくつかのトレードオフがあります。
たとえば、これらの異なる構造は、記述するJPQLクエリに影響します。
たとえば、@IdClassを使用すると、クエリは少し簡単になります:
SELECT account.accountNumber FROM Account account
@EmbeddedIdを使用すると、余分なトラバーサルを行う必要があります:
SELECT book.bookId.title FROM Book book
また、@IdClassは、変更できない複合キークラスを使用している場所で非常に便利です。
最後に、複合キーの一部に個別にアクセスする場合は、@IdClassを使用できますが、完全な識別子をオブジェクトとして頻繁に使用する場所では、@EmbeddedIdが優先され
結論
このクイック記事では、JPAの複合主キーについて説明します。
いつものように、この記事の完全なコードはGithubで見つけることができます。