JPA: Unterschied zwischen @JoinColumn und @PrimaryKeyJoinColumn?

81

Was ist der genaue Unterschied zwischen @JoinColumnund @PrimaryKeyJoinColumn?

Sie verwenden @JoinColumnfür Spalten, die Teil eines Fremdschlüssels sind. Eine typische Spalte könnte folgendermaßen aussehen (z. B. in einer Verknüpfungstabelle mit zusätzlichen Attributen):

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

Was passiert, wenn ich die Spalte auch als PK bewerbe (auch als identifizierende Beziehung bezeichnet)? Da die Spalte jetzt die PK ist, muss ich sie mit @Idfolgendem Tag versehen :

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

Nun ist die Frage:

Sind @Id+ @JoinColumngleich wie @PrimaryKeyJoinColumn?

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

Wenn nicht, wofür @PrimaryKeyJoinColumn?

Kawu
quelle

Antworten:

52

Was passiert, wenn ich die Spalte auch als PK bewerbe (auch als identifizierende Beziehung bezeichnet)? Da die Spalte jetzt die PK ist, muss ich sie mit @Id (...) kennzeichnen.

Diese erweiterte Unterstützung abgeleiteter Bezeichner ist Teil der neuen Funktionen in JPA 2.0 (siehe Abschnitt 2.4.1 Primärschlüssel für abgeleitete Identitäten in der JPA 2.0-Spezifikation). JPA 1.0 lässt Idein OneToOneoder nicht zu ManyToOne. Mit JPA 1.0 müssten Sie PrimaryKeyJoinColumneine Basic IdZuordnung für die Fremdschlüsselspalte verwenden und auch definieren .

Die Frage ist nun: Sind @Id + @JoinColumn dasselbe wie nur @PrimaryKeyJoinColumn?

Sie können ein ähnliches Ergebnis erhalten , aber unter Verwendung eines Idauf OneToOneoder ManyToOneist viel einfacher und ist die bevorzugte Art und Weise abgeleitet Identifikatoren mit JPA 2.0 abzubilden. PrimaryKeyJoinColumnkann weiterhin in einer JOINED- Vererbungsstrategie verwendet werden. Unterhalb des relevanten Abschnitts aus der JPA 2.0-Spezifikation:

11.1.40 PrimaryKeyJoinColumn-Annotation

Die PrimaryKeyJoinColumnAnmerkung gibt eine Primärschlüsselspalte an, die als Fremdschlüssel zum Verknüpfen mit einer anderen Tabelle verwendet wird.

Die PrimaryKeyJoinColumnAnnotation wird verwendet, um die Primärtabelle einer Entitätsunterklasse in der JOINED Zuordnungsstrategie mit der Primärtabelle ihrer Oberklasse zu verbinden. Es wird innerhalb einer SecondaryTableAnnotation verwendet, um eine sekundäre Tabelle mit einer primären Tabelle zu verbinden. und es kann in einer OneToOne Zuordnung verwendet werden, in der der Primärschlüssel der referenzierenden Entität als Fremdschlüssel für die referenzierte Entität verwendet wird [108] .

...

Wenn PrimaryKeyJoinColumn für eine Unterklasse in der Zuordnungsstrategie JOINED keine Anmerkung angegeben ist, wird angenommen, dass die Fremdschlüsselspalten dieselben Namen haben wie die Primärschlüsselspalten der Primärtabelle der Oberklasse.

...

Beispiel: Unterklasse Customer und 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] Die in Abschnitt 2.4.1.1 beschriebenen abgeleiteten ID-Mechanismen sind nun PrimaryKeyJoinColumnfür den OneToOne-Mapping-Fall vorzuziehen.

Siehe auch


Diese Quelle http://weblogs.java.net/blog/felipegaucho/archive/2009/10/24/jpa-join-table-additional-state besagt, dass die Verwendung von @ManyToOne und @Id mit JPA 1.x funktioniert. Wer ist jetzt richtig?

Der Autor verwendet eine JPA 2.0- kompatible Vorabversion von EclipseLink (Version 2.0.0-M7 zum Zeitpunkt des Artikels), um einen Artikel über JPA 1.0 (!) Zu schreiben. Dieser Artikel ist irreführend. Der Autor verwendet etwas, das NICHT Teil von JPA 1.0 ist.

Für die Aufzeichnung wurde die Unterstützung von Idon OneToOneund ManyToOnein EclipseLink 1.1 hinzugefügt (siehe diese Nachricht von James Sutherland , EclipseLink-Comitter und Hauptverantwortlicher des Java Persistence- Wiki-Buches). Aber lassen Sie mich darauf bestehen, dass dies NICHT Teil von JPA 1.0 ist.

Pascal Thivent
quelle
Diese Quelle weblogs.java.net/blog/felipegaucho/archive/2009/10/24/… besagt, dass die Verwendung von @ManyToOne und @Id mit JPA 1.x funktioniert. Wer ist jetzt richtig?
Kawu
OK. Danke, dass du das geklärt hast. Ich habe Recht, dass das schlechte Beispiel, auf das verwiesen wird, @IdClass falsch verwendet? Sollten die @ ID-Annotationen nicht an den separaten (redundanten / doppelten) Spalten in der Entitätsklasse platziert werden, um korrekt zu sein? (obwohl ich weiß, dass die Verwendung von @IdClass nicht mehr empfohlen wird)
Kawu
Ich meine, es sollte zwei Eigenschaften in der Klasse geben: @Id @Column private String institution; und @Id @Column privater String-Wettbewerb; nur um die PK anzugeben, oder?
Kawu
@ Kawu Es tut mir leid, aber ehrlich gesagt ist es zu schwer, dies in einem kleinen Kommentarfeld zu diskutieren. Ich bin mir nicht mal sicher, ob ich verstanden habe, wovon du sprichst. Wenn Sie eine andere spezielle Frage haben, empfehle ich, entweder eine JPA-Implementierung auszuwählen und ein wenig zu experimentieren oder eine neue Frage mit einem vollständigen Beispiel (und der JPA-Version) zu posten . Dies würde die Dinge viel einfacher machen.
Pascal Thivent
37

Normalerweise unterscheide ich diese beiden anhand dieses Diagramms:

Verwenden PrimaryKeyJoinColumn

Geben Sie hier die Bildbeschreibung ein

Verwenden JoinColumn

Geben Sie hier die Bildbeschreibung ein

Sam YC
quelle
2
@yusher, PrimaryKeyJoinColumnverwenden Sie denselben Primärschlüsselwert, um zwei Tabellen zu verbinden, und JoinColumnder Primärschlüssel der Haupttabelle wird in einer anderen Tabelle zum Fremdschlüssel.
Sam YC
2

Ich weiß, dass dies ein alter Beitrag ist, aber ein guter Zeitpunkt PrimaryKeyColumnwäre, wenn Sie eine unidirektionale Beziehung wünschen oder mehrere Tabellen haben, die alle dieselbe ID haben.

Im Allgemeinen ist dies eine schlechte Idee und es wäre besser, Fremdschlüsselbeziehungen mit zu verwenden JoinColumn.

Wenn Sie jedoch an einer älteren Datenbank arbeiten, die ein solches System verwendet, ist dies ein guter Zeitpunkt, um es zu verwenden.

Philip Read
quelle