Articles

Hibernate One to Many Annotation Tutorial

Einführung

Dieses kurze Hibernate-Tutorial führt uns durch ein Beispiel für ein Eins-zu-Viele-Mapping mit JPA-Annotationen, einer Alternative zu XML.

Wir werden auch lernen, was bidirektionale Beziehungen sind, wie sie Inkonsistenzen erzeugen können und wie die Idee des Eigentums helfen kann.

Weiterführende Literatur:

Spring Boot mit Hibernate

Eine schnelle, praktische Einführung in die Integration von Spring Boot und Hibernate /JPA.
Lesen Sie mehr →

Eine Übersicht über Bezeichner in Hibernate / JPA

Erfahren Sie, wie Sie Entitätsbezeichner mit Hibernate zuordnen.
Weiterlesen →

Beschreibung

Einfach ausgedrückt bedeutet One-to-Many-Mapping, dass eine Zeile in einer Tabelle mehreren Zeilen in einer anderen Tabelle zugeordnet wird.

Schauen wir uns das folgende Entity-Relationship-Diagramm an, um eine Eins-zu-Viele-Zuordnung zu sehen:

In diesem Beispiel implementieren wir ein Warenkorbsystem, in dem wir eine Tabelle für jeden Warenkorb und eine weitere Tabelle für jeden Artikel haben. Ein Warenkorb kann viele Artikel enthalten, daher haben wir hier eine Eins-zu-Viele-Zuordnung.

Dies funktioniert auf Datenbankebene so, dass wir eine cart_id als Primärschlüssel in der cart-Tabelle und eine cart_id als Fremdschlüssel in items haben.

Die Art, wie wir es im Code machen, ist mit @OneToMany .

Ordnen wir die Cart-Klasse dem Items-Objekt so zu, dass sie die Beziehung in der Datenbank widerspiegelt:

public class Cart { //... @OneToMany(mappedBy="cart") private Set<Items> items; //...}

Wir können auch einen Verweis auf Cart in Items mit @ManyToOne hinzufügen, wodurch dies zu einer bidirektionalen Beziehung wird. Bidirektional bedeutet, dass wir auf Artikel aus Warenkörben und auch auf Artikel aus Artikeln zugreifen können.

Mit der Eigenschaft mappedBy teilen wir Hibernate mit, welche Variable wir zur Darstellung der übergeordneten Klasse in unserer untergeordneten Klasse verwenden.

Die folgenden Technologien und Bibliotheken werden verwendet, um eine Beispiel-Hibernate-Anwendung zu entwickeln, die eine Eins-zu-Viele-Zuordnung implementiert:

  • JDK 1.8 oder höher
  • Hibernate 5
  • Maven 3 oder höher
  • H2-Datenbank

Setup

3.1. Datenbank-Setup

Nachfolgend finden Sie unser Datenbankskript für Warenkorb- und Artikeltabellen. Wir verwenden die Fremdschlüsseleinschränkung für die Eins-zu-Viele-Zuordnung:

Unser Datenbank-Setup ist fertig.

3.2. Maven-Abhängigkeiten

Wir fügen dann die Abhängigkeiten von Hibernate und H2-Treiber zu unserem Pom hinzu.xml-Datei. Die Hibernate-Abhängigkeit verwendet die JBoss-Protokollierung und wird automatisch als transitive Abhängigkeiten hinzugefügt:

  • Hibernate Version 5.2.7.Endgültige
  • H2-Treiberversion 1.4.197

Bitte besuchen Sie das Maven Central Repository für die neuesten Versionen von Hibernate und die H2-Abhängigkeiten.

3.3. Hibernate-Konfiguration

Hier ist die Konfiguration von Hibernate:

3.4. HibernateAnnotationUtil-Klasse

Mit der HibernateAnnotationUtil-Klasse müssen wir nur auf die neue Hibernate-Konfigurationsdatei verweisen:

Die Modelle

Die Mapping-bezogenen Konfigurationen werden mit JPA-Annotationen in den Modellklassen durchgeführt:

@Entity@Table(name="CART")public class Cart { //... @OneToMany(mappedBy="cart") private Set<Items> items; // getters and setters}

Bitte beachten Sie, dass die Annotation @OneToMany verwendet wird, um die Eigenschaft in der Klasse zu definieren, die zum Zuordnen der Variablen mappedBy verwendet wird. Aus diesem Grund haben wir eine Eigenschaft namens „cart“ in der Items-Klasse:

Es ist auch wichtig zu beachten, dass die Annotation @ManyToOne der Cart-Klassenvariablen zugeordnet ist. @JoinColumn Annotation verweist auf die zugeordnete Spalte.

In Aktion

Im Testprogramm erstellen wir eine Klasse mit einer main() -Methode, um die Hibernate-Sitzung abzurufen und die Modellobjekte in der Datenbank zu speichern, die die Eins-zu-Viele-Assoziation implementiert:

Dies ist die Ausgabe unseres Testprogramms:

Die Annotation @ManyToOne

Wie wir in Abschnitt 2 gesehen haben, können wir eine eins-zu-Eins-Beziehung mithilfe der Annotation @ManyToOne. Eine Viele-zu-Eins-Zuordnung bedeutet, dass viele Instanzen dieser Entität einer Instanz einer anderen Entität zugeordnet werden – viele Artikel in einem Warenkorb.

Mit der Annotation @ManyToOne können wir auch bidirektionale Beziehungen erstellen. Wir werden dies in den nächsten Unterabschnitten ausführlich behandeln.

6.1. Inkonsistenzen und Eigentumsverhältnisse

Wenn nun der Warenkorb auf Artikel verweist, die Artikel jedoch nicht auf den Warenkorb verweisen, wäre unsere Beziehung unidirektional. Die Objekte hätten auch eine natürliche Konsistenz.

In unserem Fall ist die Beziehung jedoch bidirektional, was die Möglichkeit von Inkonsistenzen mit sich bringt.

Stellen wir uns eine Situation vor, in der ein Entwickler item1 zu cart und item2 zu cart2 hinzufügen möchte, aber einen Fehler macht, so dass die Referenzen zwischen cart2 und item2 inkonsistent werden:

Wie oben gezeigt, verweist item2 auf cart2, während cart2 nicht auf item2 verweist, und das ist schlecht.

Wie soll Hibernate item2 in der Datenbank speichern? Wird der Fremdschlüssel item2 auf cart1 oder cart2 verweisen?

Wir lösen diese Mehrdeutigkeit mit der Idee einer Besitzerseite der Beziehung; Referenzen, die zur Besitzerseite gehören, haben Vorrang und werden in der Datenbank gespeichert.

6.2. Elemente als Besitzerseite

Wie in der JPA-Spezifikation unter Abschnitt 2.9 angegeben, empfiehlt es sich, die Many-to-One-Seite als Besitzerseite zu markieren.Mit anderen Worten, Items wären die besitzende Seite und Cart die inverse Seite, was genau das ist, was wir zuvor getan haben.

Wie haben wir das erreicht?

Indem wir das mappedBy-Attribut in die Cart-Klasse aufnehmen, markieren wir es als inverse Seite.

Gleichzeitig kommentieren wir die Elemente.warenkorbfeld mit @ManyToOne, wodurch Artikel zur Besitzerseite werden.

Zurück zu unserem Beispiel „Inkonsistenz“ weiß Hibernate jetzt, dass die Referenz von item2 wichtiger ist, und speichert die Referenz von item2 in der Datenbank.

Überprüfen wir das Ergebnis:

item1 ID=1, Foreign Key Cart ID=1item2 ID=2, Foreign Key Cart ID=2

Obwohl cart in unserem Snippet auf item2 verweist, wird der Verweis von item2 auf cart2 in der Datenbank gespeichert.

6.3. Cart als Besitzerseite

Es ist auch möglich, die Eins-zu-Viele-Seite als Besitzerseite und die Viele-zu-Eins-Seite als inverse Seite zu markieren.

Obwohl dies keine empfohlene Vorgehensweise ist, probieren wir es aus.

Das folgende Code-Snippet zeigt die Implementierung der One-to-Many-Seite als Besitzerseite:

Beachten Sie, wie wir das mappedBy-Element entfernt und die many-to-one @JoinColumn als einfügbar und aktualisierbar auf false gesetzt haben.

Wenn wir denselben Code ausführen, ist das Ergebnis das Gegenteil:

item1 ID=1, Foreign Key Cart ID=1item2 ID=2, Foreign Key Cart ID=1

Wie oben gezeigt, gehört item2 jetzt zum Warenkorb.

Fazit

Wir haben gesehen, wie einfach es ist, die Eins-zu-Viele-Beziehung mit der Hibernate ORM- und H2-Datenbank mithilfe von JPA-Annotationen zu implementieren.

Zusätzlich lernten wir etwas über bidirektionale Beziehungen und wie man den Begriff einer besitzenden Seite implementiert.