Clés Primaires Composites dans JPA

Introduction

Dans ce tutoriel, nous allons en apprendre davantage sur les Clés Primaires Composites et les annotations correspondantes dans JPA.

Clés primaires composites

Une clé primaire composite – également appelée clé composite – est une combinaison de deux colonnes ou plus pour former une clé primaire pour une table.

Dans JPA, nous avons deux options pour définir les clés composites : Les annotations @IdClass et @EmbeddedId.

Afin de définir les clés primaires composites, nous devons suivre quelques règles:

  • La classe de clé primaire composite doit être publique
  • Elle doit avoir un constructeur sans arg
  • Elle doit définir les méthodes equals() et hashCode()
  • Elle doit être sérialisable

L’annotation IdClass

Soit disons que nous avons une table appelée Account et qu’elle a deux colonnes – accountNumber, accountType – qui forment la clé composite. Maintenant, nous devons le cartographier en JPA.

Selon la spécification JPA, créons une classe AccountId avec ces champs de clé primaire:

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

Ensuite, associons la classe AccountId au compte d’entité.

Pour ce faire, nous devons annoter l’entité avec l’annotation @IdClass. Nous devons également déclarer les champs de la classe AccountId dans le compte d’entité et les annoter avec @Id:

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

L’annotation EmbeddedId

@EmbeddedId est une alternative à l’annotation @IdClass.

Considérons un autre exemple où nous devons conserver certaines informations d’un livre avec le titre et la langue comme champs de clé primaire.

Dans ce cas, la classe de clé primaire, BookId, doit être annotée avec @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}

Ensuite, nous devons intégrer cette classe dans l’entité Book en utilisant @EmbeddedId:

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

@ IdClass vs @EmbeddedId

Comme nous venons de le voir, la différence en surface entre ces deux est qu’avec @IdClass, nous devions spécifier les colonnes deux fois – une fois dans AccountId et encore dans Account. Mais, avec @EmbeddedId, nous ne l’avons pas fait.

Il y a cependant d’autres compromis.

Par exemple, ces différentes structures affectent les requêtes JPQL que nous écrivons.

Par exemple, avec @IdClass, la requête est un peu plus simple:

SELECT account.accountNumber FROM Account account

Avec @EmbeddedId, nous devons faire une traversée supplémentaire:

SELECT book.bookId.title FROM Book book

De plus, @IdClass peut être très utile dans les endroits où nous utilisons une classe de clé composite que nous ne pouvons pas modifier.

Enfin, si nous allons accéder individuellement à des parties de la clé composite, nous pouvons utiliser @IdClass, mais dans les endroits où nous utilisons fréquemment l’identifiant complet comme objet, @EmbeddedId est préféré.

Conclusion

Dans cet article rapide, nous explorons les clés primaires composites dans JPA.

Comme toujours, le code complet de cet article se trouve sur Github.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée.