Training, Workshops, Softwareentwicklung

Hibernate Tutorial

Bidirektionales OneToMany

Bei einer bidirektionalen OneToMany Beziehung bildet man sowohl im Customer die Beziehung zu den Invoices ab, als auch umgekehrt die Beziehung von den Invoices zum Customer. Ein und die selbe Foreign-Key Beziehung in unserer Datenbank entspricht also zwei Objektbeziehungen in der Java-Welt.

Das Datenbankschema ist in der Einleitung zu diesem Kapitel beschrieben.

Das bidirektionale Mapping in den Entities sieht so aus:

Mapping Customer
@OneToMany(mappedBy = "customer", cascade = CascadeType.ALL) (1)
private Set<Invoice> invoices = new HashSet<>();
1 Das mappedBy liest sich wie folgt: In der Klasse auf der anderen Seite (hier Invoice, s.u.) gibt es eine Property customer, die den selben Foreign-Key mit ManyToOne beschreibt wie dieses OneToMany
Mapping Invoice
@ManyToOne(fetch = FetchType.LAZY)
private Customer customer;

Der Nachteil des unidirektionalen Mappings beim Speichern besteht nun nicht mehr:

Test
doInHibernate(em -> {

    Customer customer = new Customer();
    customer.setFirstname("Buck");
    customer.setLastname("Rogers");

    Invoice invoice = new Invoice();
    invoice.setInvoiceNo("1234");

    invoice.setCustomer(customer); (1)
    customer.getInvoices().add(invoice);


    withTransaction(em, () ->
            em.persist(customer)
    );

    withTransaction(em, () ->
            em.remove(customer)
    );
});


assertSelectCount(0);
assertInsertCount(2);
assertUpdateCount(0); (2)
assertDeleteCount(2);
1 Wir müssen unbedingt den Customer in der Invoice setzen, denn die Invoice ist das sog. owning Entity. Das heißt, am Ende des Tages wird im Zweifel das gespeichert, was in der Invoice eingetragen ist.
2 Die Updates, die wir beim unidirektionalen Mapping gesehen haben, sind hier nicht mehr erforderlich.