Was ist der Unterschied zwischen:
@Entity
public class Company {
@OneToMany(cascade = CascadeType.ALL , fetch = FetchType.LAZY)
@JoinColumn(name = "companyIdRef", referencedColumnName = "companyId")
private List<Branch> branches;
...
}
und
@Entity
public class Company {
@OneToMany(cascade = CascadeType.ALL , fetch = FetchType.LAZY, mappedBy = "companyIdRef")
private List<Branch> branches;
...
}
Antworten:
Die Anmerkung
@JoinColumn
gibt an, dass diese Entität der Eigentümer der Beziehung ist (dh die entsprechende Tabelle hat eine Spalte mit einem Fremdschlüssel für die referenzierte Tabelle), während das AttributmappedBy
angibt, dass die Entität auf dieser Seite die Umkehrung der Beziehung ist, und Der Eigentümer wohnt in der "anderen" Einheit. Dies bedeutet auch, dass Sie von der Klasse, die Sie mit "mappedBy" (vollständig bidirektionale Beziehung) kommentiert haben, auf die andere Tabelle zugreifen können.Insbesondere für den Code in der Frage würden die korrekten Anmerkungen folgendermaßen aussehen:
quelle
@JoinColumn
inCompany
Branch
keine Eigenschaft vorhanden ist, auf die verwiesenCompany
wird, die zugrunde liegende Tabelle jedoch eine entsprechende Spalte enthält, können Sie@JoinTable
sie zuordnen. Dies ist eine ungewöhnliche Situation, da Sie normalerweise die Spalte in dem Objekt zuordnen würden, das der Tabelle entspricht. Dies kann jedoch vorkommen und ist absolut legitim.@OneToOne
, werden dienull
untergeordneten Zeilen mit einem in ihrer FKey-Spalte aktualisiert , das auf das übergeordnete Element verweist.@JoinColumn
könnte auf beiden Seiten der Beziehung verwendet werden. Die Frage war über die Verwendung@JoinColumn
auf der@OneToMany
Seite (seltener Fall). Der Punkt hier ist die Duplizierung physischer Informationen (Spaltenname) zusammen mit einer nicht optimierten SQL-Abfrage, die einige zusätzlicheUPDATE
Anweisungen erzeugt .Laut Dokumentation :
Da viele zu eins (fast) immer die Eigentümerseite einer bidirektionalen Beziehung in der JPA-Spezifikation sind, wird die Eins-zu-Viele-Zuordnung von kommentiert
@OneToMany(mappedBy=...)
Troop
hat eine bidirektionale Beziehung zu einerSoldier
durch viele durch das Truppenvermögen. Sie müssen (dürfen) keine physische Zuordnung in dermappedBy
Seite definieren.Um eine bidirektionale Eins -zu-Viele-Seite mit der Eins-zu-Viele-Seite als Besitzerseite zuzuordnen , müssen Sie das
mappedBy
Element entfernen und die Viele auf Eins@JoinColumn
alsinsertable
undupdatable
auf Falsch setzen. Diese Lösung ist nicht optimiert und führt zu einigen zusätzlichenUPDATE
Anweisungen.quelle
mappedBy="troop"
bezieht sich die Anmerkung auf welches Feld?mappedBy="troop"
bezieht sich auf die Eigenschaftstruppe in der Klasse Soldat. Im obigen Code ist die Eigenschaft nicht sichtbar, da Mykhaylo sie hier weggelassen hat, aber Sie können ihre Existenz durch den Getter getTroop () ableiten. Überprüfen Sie die Antwort von Óscar López , es ist sehr klar und Sie werden den Punkt bekommen.Unidirektionale Eins-zu-Viele-Assoziation
Wie ich in diesem Artikel erklärt habe , haben Sie, wenn Sie die
@OneToMany
Annotation mit verwenden@JoinColumn
, eine unidirektionale Zuordnung, wie die zwischen der übergeordnetenPost
Entität und dem untergeordneten ElementPostComment
in der folgenden Abbildung:Bei Verwendung einer unidirektionalen Eins-zu-Viele-Zuordnung ordnet nur die übergeordnete Seite die Zuordnung zu.
In diesem Beispiel
Post
definiert nur die Entität eine@OneToMany
Zuordnung zur untergeordnetenPostComment
Entität:Bidirektionale Eins-zu-Viele-Assoziation
Wenn Sie das
@OneToMany
mit demmappedBy
Attributsatz verwenden, haben Sie eine bidirektionale Zuordnung. In unserem Fall verfügt sowohl diePost
Entität über eine Sammlung vonPostComment
untergeordneten Entitäten als auch die untergeordnetePostComment
Entität über einen Verweis auf die übergeordnetePost
Entität, wie in der folgenden Abbildung dargestellt:In der
PostComment
Entität wird diepost
Entitätseigenschaft wie folgt zugeordnet:In der
Post
Entität wird diecomments
Zuordnung wie folgt zugeordnet:Das
mappedBy
Attribut der@OneToMany
Annotation verweist auf diepost
Eigenschaft in der untergeordnetenPostComment
Entität. Auf diese Weise weiß Hibernate, dass die bidirektionale Zuordnung von der@ManyToOne
Seite gesteuert wird , die für die Verwaltung des Spaltenwerts für den Fremdschlüssel verantwortlich ist, auf dem diese Tabellenbeziehung basiert.Für eine bidirektionale Zuordnung benötigen Sie außerdem zwei Dienstprogrammmethoden wie
addChild
undremoveChild
:Diese beiden Methoden stellen sicher, dass beide Seiten der bidirektionalen Zuordnung nicht synchron sind. Ohne beide Enden zu synchronisieren, garantiert Hibernate nicht, dass Änderungen des Zuordnungsstatus in die Datenbank übertragen werden.
Welches soll ich wählen?
Die unidirektionale
@OneToMany
Zuordnung funktioniert nicht sehr gut , daher sollten Sie sie vermeiden.Sie sind besser dran, wenn Sie das bidirektionale verwenden,
@OneToMany
das effizienter ist .quelle
Die Annotation mappedBy sollte idealerweise immer auf der übergeordneten Seite (Company-Klasse) der bidirektionalen Beziehung verwendet werden. In diesem Fall sollte sie in der Company-Klasse sein und auf die Mitgliedsvariable 'company' der Child-Klasse (Branch-Klasse) verweisen.
Die Annotation @JoinColumn wird verwendet, um eine zugeordnete Spalte für den Beitritt zu einer Entitätszuordnung anzugeben. Diese Annotation kann in jeder Klasse (Parent oder Child) verwendet werden, sollte jedoch idealerweise nur auf einer Seite verwendet werden (entweder in der Parent-Klasse oder nicht in der Child-Klasse) in beiden) hier in diesem Fall habe ich es auf der Child-Seite (Branch-Klasse) der bidirektionalen Beziehung verwendet, die den Fremdschlüssel in der Branch-Klasse angibt.
Unten ist das Arbeitsbeispiel:
Elternklasse, Firma
Kinderklasse, Zweig
quelle
Ich möchte nur hinzufügen, dass
@JoinColumn
dies nicht immer mit dem physischen Informationsort zusammenhängen muss, wie diese Antwort nahelegt. Sie können kombinieren@JoinColumn
mit ,@OneToMany
auch wenn die übergeordnete Tabelle keine Tabellendaten zeigt auf der untergeordneten Tabelle hat.So definieren Sie eine unidirektionale OneToMany-Beziehung in JPA
Unidirektional OneToMany, No Inverse ManyToOne, No Join Table
Es scheint jedoch nur in verfügbar zu sein
JPA 2.x+
. Dies ist nützlich in Situationen, in denen die untergeordnete Klasse nur die ID des übergeordneten Elements enthalten soll und keine vollständige Referenz.quelle
Ich bin mit der hier akzeptierten Antwort von Óscar López nicht einverstanden. Diese Antwort ist ungenau!
Es ist NICHT,
@JoinColumn
was darauf hinweist, dass diese Entität der Eigentümer der Beziehung ist. Stattdessen ist es die@ManyToOne
Annotation, die dies tut (in seinem Beispiel).Die Beziehung Anmerkungen wie
@ManyToOne
,@OneToMany
und@ManyToMany
sagen , JPA / Hibernate eine Zuordnung zu erstellen. Standardmäßig erfolgt dies über eine separate Join-Tabelle.@ JoinColumn
MappedBy
Denken Sie daran:
MappedBy
ist eine Eigenschaft der Beziehungsanmerkungen, deren Zweck darin besteht, einen Mechanismus zum Verknüpfen von zwei Entitäten zu generieren, der standardmäßig durch Erstellen einer Verknüpfungstabelle erstellt wird.MappedBy
stoppt diesen Prozess in eine Richtung.Die nicht verwendete Entität
MappedBy
wird als Eigentümer der Beziehung bezeichnet, da die Mechanik der Zuordnung innerhalb ihrer Klasse durch die Verwendung einer der drei Zuordnungsanmerkungen für das Fremdschlüsselfeld bestimmt wird. Dies gibt nicht nur die Art der Zuordnung an, sondern weist auch die Erstellung einer Verknüpfungstabelle an. Darüber hinaus besteht die Option zum Unterdrücken der Join-Tabelle auch durch Anwenden der Annotation @JoinColumn auf den Fremdschlüssel, wodurch dieser stattdessen in der Tabelle der Eigentümerentität verbleibt.Zusammenfassend
@JoinColumn
lässt sich sagen, dass entweder eine neue Join-Spalte erstellt oder eine vorhandene umbenannt wird. Während derMappedBy
Parameter mit den Beziehungsanmerkungen der anderen (untergeordneten) Klasse zusammenarbeitet, um eine Zuordnung entweder über eine Verknüpfungstabelle oder durch Erstellen einer Fremdschlüsselspalte in der zugeordneten Tabelle der Eigentümerentität zu erstellen.Beachten Sie
MapppedBy
den folgenden Code, um die Funktionsweise zu veranschaulichen . WennMappedBy
Parameter gelöscht würden, würde Hibernate tatsächlich ZWEI Join-Tabellen erstellen! Warum? Weil es eine Symmetrie in vielen-zu-vielen-Beziehungen gibt und der Ruhezustand keine Gründe hat, eine Richtung über die andere zu wählen.Wir verwenden daher
MappedBy
, um Hibernate mitzuteilen, dass wir die andere Entität ausgewählt haben, um die Zuordnung der Beziehung zwischen den beiden Entitäten zu diktieren.Durch Hinzufügen von @JoinColumn (name = "driverID") in der Eigentümerklasse (siehe unten) wird die Erstellung einer Join-Tabelle verhindert. Erstellen Sie stattdessen eine driverID-Fremdschlüsselspalte in der Cars-Tabelle, um eine Zuordnung zu erstellen:
quelle
JPA ist eine geschichtete API, die verschiedenen Ebenen haben ihre eigenen Anmerkungen. Die höchste Ebene ist die (1) Entitätsebene, die persistente Klassen beschreibt. Dann haben Sie die (2) relationale Datenbankebene, die davon ausgeht, dass die Entitäten einer relationalen Datenbank zugeordnet sind, und (3) das Java-Modell.
Stufe 1 Anmerkungen:
@Entity
,@Id
,@OneToOne
,@OneToMany
,@ManyToOne
,@ManyToMany
. Sie können Ihrer Anwendung Persistenz verleihen, indem Sie nur diese Anmerkungen auf hoher Ebene verwenden. Aber dann müssen Sie Ihre Datenbank gemäß den von JPA getroffenen Annahmen erstellen. Diese Anmerkungen geben das Entitäts- / Beziehungsmodell an.Stufe 2 Anmerkungen:
@Table
,@Column
,@JoinColumn
, ... Einfluss die Zuordnung von Einheiten / Eigenschaften zu den relationalen Datenbanktabellen / Spalten , wenn Sie nicht mit PPV-Vorgaben erfüllt sind oder wenn Sie in eine bestehende Datenbank abzubilden. Diese Anmerkungen können als Implementierungsanmerkungen angesehen werden. Sie geben an, wie die Zuordnung erfolgen soll.Meiner Meinung nach ist es am besten, sich so weit wie möglich an die Anmerkungen auf hoher Ebene zu halten und dann die Anmerkungen auf niedrigerer Ebene nach Bedarf einzuführen.
Um die Fragen zu beantworten: Das
@OneToMany
/mappedBy
ist am schönsten, da es nur die Anmerkungen aus der Entitätsdomäne verwendet. Das@oneToMany
/@JoinColumn
ist ebenfalls in Ordnung, verwendet jedoch eine Implementierungsanmerkung, wenn dies nicht unbedingt erforderlich ist.quelle
Lassen Sie es mich einfach machen.
Sie können @JoinColumn unabhängig von der Zuordnung auf beiden Seiten verwenden.
Teilen wir dies in drei Fälle ein.
1) Unidirektionale Zuordnung von der Niederlassung zur Firma.
2) Bidirektionale Zuordnung von Unternehmen zu Niederlassung.
3) Nur unidirektionale Zuordnung von Unternehmen zu Niederlassung.
Jeder Anwendungsfall fällt also unter diese drei Kategorien. Lassen Sie mich erklären, wie Sie @JoinColumn und mappedBy verwenden .
1) Unidirektionale Zuordnung von der Niederlassung zur Firma.
Verwenden Sie JoinColumn in der Branch-Tabelle.
2) Bidirektionale Zuordnung von Unternehmen zu Niederlassung.
Verwenden Sie mappedBy in der Firmentabelle, wie in der Antwort von @Mykhaylo Adamovych beschrieben.
3) Unidirektionale Zuordnung von Unternehmen zu Niederlassung.
Verwenden Sie einfach @JoinColumn in der Firmentabelle .
Dies besagt, dass ich auf der Grundlage der Fremdschlüsselzuordnung "courseId" in der Verzweigungstabelle eine Liste aller Zweige abrufen kann. HINWEIS: In diesem Fall können Sie keine Firma von der Niederlassung abrufen. Es gibt nur eine unidirektionale Zuordnung von Firma zu Niederlassung.
quelle