Samengestelde primaire sleutels in JPA

1. Inleiding

In deze zelfstudie leren we over samengestelde primaire sleutels en de bijbehorende annotaties in JPA.

2. Samengestelde primaire sleutels

Een samengestelde primaire sleutel - ook wel een samengestelde sleutel genoemd - is een combinatie van twee of meer kolommen om een ​​primaire sleutel voor een tabel te vormen.

In JPA hebben we twee opties om de samengestelde sleutels te definiëren: De @IdClass en @EmbeddedId annotaties.

Om de samengestelde primaire sleutels te definiëren, moeten we enkele regels volgen:

  • De samengestelde primaire-sleutelklasse moet openbaar zijn
  • Het moet een constructor zonder argumenten hebben
  • Het moet definiëren is gelijk aan () en hashCode () methoden
  • Het moet zijn Serialiseerbaar

3. Het IdClass Annotatie

Laten we zeggen dat we een tafel hebben gebeld Account en het heeft twee kolommen - accountNumber, accountType - die de samengestelde sleutel vormen. Nu moeten we het in JPA in kaart brengen.

Laten we volgens de JPA-specificatie een Account ID klasse met deze primaire sleutelvelden:

openbare klasse AccountId implementeert Serializable {private String accountNumber; privé String accountType; // standaard constructor openbare AccountId (String accountNumber, String accountType) {this.accountNumber = accountNumber; this.accountType = accountType; } // equals () en hashCode ()}

Laten we vervolgens het Account ID klasse met de entiteit Account.

Om dat te doen, moeten we de entiteit annoteren met de @IdClass annotatie. We moeten ook de velden van de Account ID klasse in de entiteit Account en annoteer ze met @ID kaart:

@Entity @IdClass (AccountId.class) openbare klasse Account {@Id private String accountNumber; @Id private String accountType; // andere velden, getters en setters}

4. Het EmbeddedId Annotatie

@EmbeddedId is een alternatief voor de @IdClass annotatie.

Laten we een ander voorbeeld bekijken waarin we wat informatie van een Boek met titel en taal als de primaire sleutelvelden.

In dit geval is de primaire sleutelklasse, Boek-id, moet worden geannoteerd met @Embeddable:

@Embeddable public class BookId implementeert Serializable {private String title; privé String-taal; // standaard constructor openbare BookId (String-titel, String-taal) {this.title = title; this.language = taal; } // getters, equals () en hashCode () methoden}

Vervolgens moeten we deze klasse insluiten in het Book entiteit met @EmbeddedId:

@Entity openbare klasse Book {@EmbeddedId privé BookId bookId; // constructeurs, andere velden, getters en setters}

5. @IdClass vs @EmbeddedId

Zoals we net hebben gezien, is het verschil op het oppervlak tussen deze twee dat met @IdClass, moesten we de kolommen twee keer specificeren - een keer in Account ID en weer in Account. Maar met @EmbeddedId wij niet.

Er zijn echter enkele andere afwegingen.

Deze verschillende structuren zijn bijvoorbeeld van invloed op de JPQL-query's die we schrijven.

Bijvoorbeeld met @IdClass, de vraag is een beetje eenvoudiger:

SELECTEER account.accountNumber VAN Accountaccount

Met @EmbeddedId, we moeten een extra traversal doen:

SELECTEER book.bookId.title FROM Boek boek

Ook, @IdClass kan heel handig zijn op plaatsen waar wegebruiken een samengestelde sleutelklasse die we niet kunnen wijzigen.

Ten slotte, als we delen van de samengestelde sleutel afzonderlijk gaan benaderen, kunnen we gebruik maken van @IdClass, maar op plaatsen waar we vaak de volledige identifier als object gebruiken, @EmbeddedId heeft de voorkeur.

6. Conclusie

In dit korte artikel onderzoeken we samengestelde primaire sleutels in JPA.

Zoals altijd is de volledige code voor dit artikel te vinden op Github.