Training, Workshops, Softwareentwicklung

Hibernate Tutorial

Lazy Loading

Bei den ToMany Beziehungen ist per default das sog. Lazy Loading aktiviert.

LazyLoadingTest
TypedQuery<Customer> query =
        em.createQuery("SELECT c FROM Customer c", Customer.class);
Customer customer = query.getSingleResult(); (1)

for (Invoice invoice : customer.getInvoices()) { (2)
    assertEquals("1234", invoice.getInvoiceNo());
}
assertSelectCount(2);
1 Bei diesem Zugriff wird nur der Customer geladen.
2 Erst wenn wir auf die Invoices zugreifen, werden die Invoices "Lazy" nachgeladen.
Query:["select customer0_.id as id1_0_, customer0_.firstname as firstnam2_0_, customer0_.lastname as lastname3_0_ from Customer customer0_"], Params:[()]
Query:["select invoices0_.customer_id as customer3_1_0_, invoices0_.id as id1_1_0_, invoices0_.id as id1_1_1_, invoices0_.invoiceNo as invoiceN2_1_1_ from Invoice invoices0_ where invoices0_.customer_id=?"], Params:[(1)]

Obwohl also im Code nur ein Select zu sehen ist, haben wir hier tatsächlich zwei Selects programmiert.

Hier zum "Beweis" noch ein Screen-cast:

Ein klassischer Stolperstein ist die Tatsache, dass das nur solange funktioniert, wie der dazugehörige EntityManager nicht geschlossen wurde.

LazyInitializationException
@Test(expected = LazyInitializationException.class)
public void testLazyLoadingException() {

    Customer customer = callInHibernate(em -> {
        TypedQuery<Customer> query =
                em.createQuery("SELECT c FROM Customer c", Customer.class);
        return query.getSingleResult(); (1)
    });

    for (Invoice invoice : customer.getInvoices()) { (2)
        assertEquals("1234", invoice.getInvoiceNo());
    }
}
1 Bei diesem Zugriff wird nur der Customer geladen.
2 Der EntityManager ist geschlossen. Wenn wir jetzt auf die Invoices zugreifen, erhalten wir eine LazyInitializationException.
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: de.eiswind.training.hibernate.domain.Customer.invoices, could not initialize proxy - no Session