Java Academy · Lektion

One-to-Many- und Many-to-Many-Beziehungen

Ordnen Sie @OneToMany, @ManyToMany und @JoinTable mit Kaskadentypen und Fetch-Strategien zu.

Lektion 3 von 413 Schritte

One-to-Many- und Many-to-Many-Beziehungen ist eine kostenlose Java Academy-Lektion auf CoddyKit. Dies ist Lektion 3 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des Java Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der Java Academy-Kurs umfasst insgesamt 4 Lektionen.

Beziehungstypen in JPA

JPA unterstützt vier Beziehungstypen: @OneToOne, @OneToMany, @ManyToOne, @ManyToMany. Jeder Typ wird auf Fremdschlüssel- oder Join-Table-Einschränkungen abgebildet.

@ManyToOne: Die besitzende Seite

Eine Many-to-one-Beziehung (z. B. viele Orders gehören zu einem User) wird mit @ManyToOne und einer @JoinColumn für den Fremdschlüssel abgebildet.

@Entity
public class Order {
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "user_id", nullable = false)
    private User user;
}

@OneToMany: Die inverse Seite

Die inverse Seite (ein User hat viele Orders) verwendet @OneToMany(mappedBy = "user"). Das Attribut mappedBy verweist auf das Feld auf der besitzenden Seite, das den FK enthält.

@Entity
public class User {
    @OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<Order> orders = new ArrayList<>();
}

Hilfsmethode für bidirektionale Konsistenz

Bei bidirektionalen Beziehungen sollten Sie beide Seiten der Beziehung in einer Hilfsmethode pflegen, damit der Objektgraph vor dem Flushen konsistent bleibt.

public void addOrder(Order order) {
    orders.add(order);
    order.setUser(this); // keep both sides in sync
}
public void removeOrder(Order order) {
    orders.remove(order);
    order.setUser(null);
}

Kaskadentypen

CascadeType.ALL überträgt alle Operationen (persist, merge, remove, refresh, detach) vom übergeordneten Objekt auf das untergeordnete. PERSIST und MERGE sind häufig sinnvolle und sichere Optionen. REMOVE löscht untergeordnete Objekte, wenn das übergeordnete Objekt gelöscht wird.

@OneToMany(mappedBy = "user",
           cascade = {CascadeType.PERSIST, CascadeType.MERGE},
           orphanRemoval = true)
private List<Order> orders;

orphanRemoval: Automatisches Löschen untergeordneter Objekte

orphanRemoval = true löscht eine untergeordnete Entität, wenn sie aus der Collection des übergeordneten Objekts entfernt wird – auch ohne einen expliziten Aufruf von entityManager.remove().

user.getOrders().remove(order); // triggers DELETE for the orphaned order on flush

@ManyToMany mit @JoinTable

Eine Many-to-many-Beziehung (z. B. zwischen Student und Course) verwendet eine Verknüpfungstabelle. Definieren Sie sie auf der besitzenden Seite mit @JoinTable; die inverse Seite verwendet mappedBy.

@Entity
public class Student {
    @ManyToMany
    @JoinTable(
        name = "student_course",
        joinColumns = @JoinColumn(name = "student_id"),
        inverseJoinColumns = @JoinColumn(name = "course_id"))
    private Set<Course> courses = new HashSet<>();
}

Zusätzliche Spalten in der Verknüpfungstabelle

Wenn die Verknüpfungstabelle zusätzliche Spalten benötigt (z. B. das Einschreibedatum), ersetzen Sie @ManyToMany durch zwei Beziehungen – @OneToMany und @ManyToOne – mit einer neuen Entität, die die Verknüpfungstabelle repräsentiert.

@Entity
public class Enrollment {
    @ManyToOne Student student;
    @ManyToOne Course course;
    private LocalDate enrolledAt;
}

FetchType: LAZY vs. EAGER

Standard-Fetch-Verhalten: @ManyToOne und @OneToOne sind EAGER (werden sofort geladen). @OneToMany und @ManyToMany sind LAZY (werden beim Zugriff geladen). Verwenden Sie für Collections immer LAZY, um N+1-Abfragen zu vermeiden.

// Always override to LAZY:
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "category_id")
private Category category;

N+1-Abfrageproblem

Wenn Sie innerhalb einer Schleife auf eine Lazy-Collection zugreifen, wird pro Entität eine Abfrage ausgeführt (N+1). Beheben Sie das Problem mit JOIN FETCH in JPQL oder mit @EntityGraph, um die Collection mit einer einzigen Abfrage zu laden.

// N+1 problem:
List<User> users = repo.findAll();
users.forEach(u -> u.getOrders().size()); // 1 + N queries!
// Fix:
@Query("SELECT u FROM User u LEFT JOIN FETCH u.orders")
List<User> findAllWithOrders();

Set vs. List bei Collections

Verwenden Sie Set für @ManyToMany (verhindert doppelte Zeilen in der Verknüpfungstabelle). Verwenden Sie List für @OneToMany, wenn die Reihenfolge relevant ist. Verwenden Sie niemals List mit @ManyToMany – Hibernate löscht dadurch alle Zeilen und fügt sie anschließend erneut ein.

Kurze Überprüfung

Was gibt mappedBy in einer @OneToMany-Annotation an?

Zusammenfassung

Verwenden Sie @ManyToOne+@JoinColumn auf der besitzenden (FK-)Seite. Verwenden Sie @OneToMany(mappedBy=...) auf der inversen Seite. Collections sollten immer LAZY geladen werden. Beheben Sie N+1-Abfragen mit JOIN FETCH. Verwenden Sie bei Many-to-many-Beziehungen mit zusätzlichen Spalten eine Verknüpfungsentität.

Kostenlos starten

Lerne Java mit einem KI-Tutor — kostenlos

Schreibe und führe echten Code in deinem Browser aus, bekomme sofortige Hilfe von einem 24/7 KI-Tutor und setze dein Lernen im Web oder in der App fort.

Kurse
104
Lektionen
374

Häufig gestellte Fragen

Ist die Lektion „One-to-Many- und Many-to-Many-Beziehungen“ kostenlos?

Ja — der vollständige Text von „One-to-Many- und Many-to-Many-Beziehungen“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des Java Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der Java Academy-Kurs umfasst insgesamt 4 Lektionen.

Was lerne ich in „One-to-Many- und Many-to-Many-Beziehungen“?

Ordnen Sie @OneToMany, @ManyToMany und @JoinTable mit Kaskadentypen und Fetch-Strategien zu. Du übst Java Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.

Brauche ich Erfahrung, um Java Academy zu starten?

Keine Vorkenntnisse erforderlich. Java Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 3 von 4.

Wie lange dauert die Lektion „One-to-Many- und Many-to-Many-Beziehungen“?

Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.

Kann ich in dieser Java Academy-Lektion Code schreiben und ausführen?

Ja. Jede Java Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.

Alle Lektionen in diesem Kurs

  1. Entity-Mapping mit JPA-Annotationen
  2. Spring-Data-Repositories und Abfragemethoden
  3. One-to-Many- und Many-to-Many-Beziehungen
  4. Seitennummerierung, Sortierung und Projektionen
← Zurück zu Java Academy