web-dev-qa-db-fra.com

JPA: différence entre @JoinColumn et @PrimaryKeyJoinColumn?

Quelle est la différence exacte entre @JoinColumn et @PrimaryKeyJoinColumn?

Tu utilises @JoinColumn pour les colonnes faisant partie d'une clé étrangère. Une colonne typique pourrait ressembler à (par exemple, une table de jointure avec des attributs supplémentaires):

@ManyToOne
@JoinColumn(name = "...")
private OtherClass oc;

Que se passe-t-il si la colonne est également considérée comme une/PK (relation d'identification a.k.a.)? Comme la colonne est maintenant la PK, je dois la taguer avec @Id:

@Id
@ManyToOne
@JoinColumn(name = "...")
private OtherClass oc;

Maintenant la question est:

Sont @Id + @JoinColumn le même que juste @PrimaryKeyJoinColumn ?::

@ManyToOne
@PrimaryKeyJoinColumn(name = "...")
private OtherClass oc;

Si non, qu'est-ce que @PrimaryKeyJoinColumn là pour?

73
Kawu

Que se passe-t-il si la colonne est également considérée comme une/PK (relation d'identification a.k.a.)? Comme la colonne est maintenant la PK, je dois la taguer avec @Id (...).

Cette prise en charge améliorée de identifiants dérivés fait en réalité partie de nouveautés de JPA 2. (voir la section 2.4.1 Clés primaires correspondant aux identités dérivées dans la spécification JPA 2.0), JPA 1.0 n'autorise pas Id sur un OneToOne ou ManyToOne. Avec JPA 1.0, vous deviez utiliser PrimaryKeyJoinColumn et définir également un mappage BasicId pour la colonne de clé étrangère.

Maintenant la question est: Est-ce que @Id + @JoinColumn est identique à @PrimaryKeyJoinColumn?

Vous pouvez obtenir un résultat similaire, mais en utilisant un Id sur OneToOne ou ManyToOne est beaucoup plus simple et constitue le moyen privilégié de mapper des identifiants dérivés avec JPA 2.0. PrimaryKeyJoinColumn pourrait toujours être utilisé dans une stratégie d'héritage [~ # ~] jointe [~ # ~]. Ci-dessous la section pertinente de la spécification JPA 2.0:

11.1.40 PrimaryKeyJoinColumn Annotation

L'annotation PrimaryKeyJoinColumn spécifie une colonne de clé primaire utilisée en tant que clé étrangère pour rejoindre une autre table.

L'annotation PrimaryKeyJoinColumn est utilisée pour joindre la table primaire d'une sous-classe d'entités dans la stratégie de mappage JOINED à la table primaire de sa superclasse; il est utilisé dans une annotation SecondaryTable pour joindre une table secondaire à une table primaire; et il peut être utilisé dans un mappage OneToOne dans lequel la clé primaire de l'entité faisant référence est utilisée comme clé étrangère de l'entité référencée[108].

...

Si aucune annotation PrimaryKeyJoinColumn n'est spécifiée pour une sous-classe dans la stratégie de mappage JOINED, les colonnes de clé étrangère sont supposées porter les mêmes noms que les colonnes de clé primaire de la table primaire de la superclasse.

...

Exemple: Sous-classe Client et ValuedCustomer

@Entity
@Table(name="CUST")
@Inheritance(strategy=JOINED)
@DiscriminatorValue("CUST")
public class Customer { ... }

@Entity
@Table(name="VCUST")
@DiscriminatorValue("VCUST")
@PrimaryKeyJoinColumn(name="CUST_ID")
public class ValuedCustomer extends Customer { ... }

[108] Les mécanismes d'identifiant dérivés décrits dans la section 2.4.1.1 doivent maintenant être préférés à PrimaryKeyJoinColumn pour le cas de mappage OneToOne.

Voir également


Cette source http://weblogs.Java.net/blog/felipegaucho/archive/2009/10/24/jpa-join-table-additional-state indique que l'utilisation de @ManyToOne et de @Id fonctionne avec JPA 1.x. Qui est correct maintenant?

L'auteur utilise une pré-version JPA 2.0 version compatible d'EclipseLink (version 2.0.0-M7 au moment de l'article) pour écrire un article sur JPA 1.0. (!) Cet article est trompeur, l'auteur utilise quelque chose qui fait [~ # ~] pas [~ # ~] une partie de JPA 1.0.

Pour mémoire, le support de Id sur OneToOne et ManyToOne a été ajouté dans EclipseLink 1.1 (voir ce message de James Sutherland , rédacteur EclipseLink et principal contributeur du livre wiki Java Persistence ). Mais laissez-moi insister, ceci est [~ # ~] pas [~ # ~] une partie de JPA 1.0.

49
Pascal Thivent

Je différencie normalement ces deux via ce diagramme:

Utilisez PrimaryKeyJoinColumn

enter image description here

Utilisez JoinColumn

enter image description here

22
GMsoF

Je sais que ceci est un ancien post, mais le bon moment pour utiliser PrimaryKeyColumn serait si vous vouliez une relation unidirectionnelle ou si plusieurs tables partagent le même identifiant.

En général, c'est une mauvaise idée et il serait préférable d'utiliser des relations de clé étrangère avec JoinColumn.

Cela dit, si vous travaillez sur une base de données plus ancienne qui utilisait un système comme celui-ci, ce serait un bon moment pour l'utiliser.

1
Philip Read