Chei primare compozite în JPA

1. Introducere

În acest tutorial, vom afla despre cheile principale compozite și adnotările corespunzătoare din JPA.

2. Taste primare compozite

O cheie primară compusă - numită și cheie compusă - este o combinație de două sau mai multe coloane pentru a forma o cheie primară pentru un tabel.

În JPA, avem două opțiuni pentru a defini cheile compozitelor: @IdClass și @EmbeddedId adnotări.

Pentru a defini cheile primare compuse, ar trebui să respectăm câteva reguli:

  • Clasa de chei principale compozite trebuie să fie publică
  • Trebuie să aibă un constructor fără argumente
  • Trebuie să definească metodele equals () și hashCode ()
  • Trebuie să fie S erializabil

3. Adnotarea IdClass

presupunem că avem un tabel numit Account și are două coloane - accountNumber, accountType - care formează cheia compusă. Acum trebuie să o mapăm în JPA.

Conform specificațiilor JPA, să creăm o clasă AccountId cu aceste câmpuri cheie primare:

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() }

Apoi, să asociem clasa AccountId cu contul entității .

Pentru a face acest lucru, trebuie să adnotăm entitatea cu adnotarea @IdClass . De asemenea, trebuie să declarăm câmpurile din clasa AccountId din contul entității și să le adnotăm cu @Id :

@Entity @IdClass(AccountId.class) public class Account { @Id private String accountNumber; @Id private String accountType; // other fields, getters and setters }

4. Adnotarea EmbeddedId

@EmbeddedId este o alternativă la adnotarea @IdClass .

Să luăm în considerare un alt exemplu în care trebuie să persistăm unele informații despre o carte cu titlu și limbă ca câmpuri cheie principale.

În acest caz, clasa de chei primară, BookId, trebuie să fie adnotată cu @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 }

Apoi, trebuie să încorporăm această clasă în entitatea B ook folosind @EmbeddedId :

@Entity public class Book { @EmbeddedId private BookId bookId; // constructors, other fields, getters and setters }

5. @IdClass vs @EmbeddedId

După cum tocmai am văzut, diferența la suprafață dintre aceste două este că, cu @IdClass , a trebuit să specificăm coloanele de două ori - o dată în AccountId și din nou în Account. Dar, cu @EmbeddedId nu am făcut-o.

Există totuși alte compromisuri.

De exemplu, aceste structuri diferite afectează interogările JPQL pe care le scriem.

De exemplu, cu @IdClass , interogarea este puțin mai simplă:

SELECT account.accountNumber FROM Account account

Cu @EmbeddedId , trebuie să facem o traversare suplimentară:

SELECT book.bookId.title FROM Book book

De asemenea, @IdClass poate fi destul de util în locurile în care utilizăm o clasă de chei compozite pe care nu o putem modifica.

În cele din urmă, dacă vom accesa părți ale cheii compuse individual, putem folosi @IdClass, dar în locurile în care folosim frecvent identificatorul complet ca obiect, este preferat @EmbeddedId .

6. Concluzie

În acest articol rapid, explorăm cheile primare compozite în JPA.

Ca întotdeauna, codul complet pentru acest articol poate fi găsit pe Github.