GEDOPLAN
Entwicklungswerkzeuge

Detached Entities und Extended EntityManager

Entwicklungswerkzeuge

Bei unserem Workshop “Java EE 7 – Enterprise-Anwendungen ohne Ballast” auf der JAX 2016 hatte ich das Problem, dass eine Liste von Daten, die als Lazy-Collection in einem Entity enthalten waren, trotz eines Extended EntityManager nicht geladen wurden, d. h. eine Lazyload-Exception auslösten. Im Workshop haben wir das Problem damit gelöst, dass die Daten mittels Entity Graph explizit geladen wurden. Die eigentlich offensichtliche Ursache, warum uns der Extended EntityManager in dem Fall gar nicht helfen konnte, versteckte sich sprichwörtlich in dem Wald, den man schon mal vor lauter Bäumen nicht sieht. Nach dem Workshop war es nach kurzer Zeit ruhigen Nachdenkens sofort klar, waran es lag:

Im Workshop wurde eine kleine Java-EE-Webanwendung zur Verwaltung von Konferenzbeiträgen entwickelt. Sie können Sie sich hier anschauen: https://github.com/dirkweil/javaee-workshop/tree/jax16. Betrachten Sie für das hier diskutierte Problem folgende Klassen und Facelets:

  • de.gedoplan.workshop.domain.Talk
    Dies ist die erwähnte Entity. Sie enthält die Lazy-Collection speakers
  • de.gedoplan.workshop.presentation.TalkPresenter
    Diese JSF-Präsentationsklasse sorgt für das Lesen der Talks in postConstruct
  • src/main/webapp/talk/talk.xhtml sowie …/talkEdit.xhtml
    Diese Facelets arbeiten auf Basis von TalkPresenter und bilden ein Master/Detail-View-Paar: talk.xhtml zeigt alle Talks an und verzweigt zur Bearbeitung eines einzelnen Talks nach talkEdit.xhtml.

Beim Bearbeiten eines Talks, d. h. beim Übergang von talk.xhtml zu talkEdit.xhtml kam es zu besagten Lazyload-Exception, die bei ruhiger Betrachtung auch ganz erklärlich ist:

  • Die Talks werden für talk.xhtml gelesen und in einem TalkPresenter-Objekt aufbewahrt. Nach dem Request sind natürlich die ggf. genutzte Transaktion und damit auch der zum Lesen genutzte EntityManager geschlossen, die gelesenen Talks also detached.
  • Beim Übergang zu talkEdit.xhtml wird einer der gelesen Talks direkt benutzt, um die Detaildaten anzuzeigen. Und da die Talks detached sind, funktioniert das Nachladen der Lazy-Daten nicht mehr – Peng!

Im Workshop haben wir dann die Variante genutzt, schon beim initialen Lesen der Talks auch die Speaker zu lesen, was aber nur dann wiklich sinnvoll ist, wenn die Speaker tatsächlich immer gebraucht werden, was für die Master-View talk.xhtml ja nicht zutrifft.

Besser wäre es gewesen, die Daten des im Detail anzuzeigenden Talks beim Übergang von talk.xhtml zu talkEdit.xhtml einfach neu einzulesen. So ist das jetzt in der aktuell auf GitHub befindlichen Version auch gelöst, zu sehen in der Methode TalkPresenter.editTalk.

Sollte Ihnen also eine zunächst unerklärliche Lazyload-Exception entgegen springen, überlegen Sie genau, wo die betroffenen Daten herkommen und ob sie im Moment des Nachladens nicht detached sind.

Eine alternative Lösung können Sie in dem Branch des Projektes betrachten, das im Zuge des Workshops auf der W-JAX 2015 in München entwickelt wurde (https://github.com/dirkweil/javaee-workshop/tree/wjax15): Hier wurde talk.xhtml nicht in den Flow integriert, sondern erst beim Übergang von talk.xhtml zu talkEdit.xhtml ein Flow namens “editTalk” gestartet. Dadurch wurden die Daten vor dem Betreten der Detail-Seite aus der DB aktualisiert und waren beim Nachladen der Lazy-Daten nicht detached.

Man sieht: Scopes, Ladezeitpunkt und Lazyness von Entitydaten müssen aufeinander abgestimmt sein. Es braucht also ein wenig Planung vorweg, was im normalen Projektalltag auch problemlos gelingt. Bei einem teilweise recht agilen Workshop kann’s schonmal schief gehen, was ja auch Erkenntnisse bringt …

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Bitte füllen Sie dieses Feld aus.
Bitte füllen Sie dieses Feld aus.
Bitte gib eine gültige E-Mail-Adresse ein.
Sie müssen den Bedingungen zustimmen, um fortzufahren.

Autor

Diesen Artikel teilen

LinkedIn
Xing

Gibt es noch Fragen?

Fragen beantworten wir sehr gerne! Schreibe uns einfach per Kontaktformular.

Kurse

weitere Blogbeiträge

web 7048124 640 jpg
Spring

Spring Boot – Caching

Caching ist ein essenzielles Thema, wenn es um die Laufzeitoptimierung der eigenen Anwendung geht. Fachlich ist die größte Herausforderung sicherlich…

Work Life Balance. Jobs bei Gedoplan

We are looking for you!

Lust bei GEDOPLAN mitzuarbeiten? Wir suchen immer Verstärkung – egal ob Entwickler, Dozent, Trainerberater oder für unser IT-Marketing! Schau doch einfach mal auf unsere Jobseiten! Wir freuen uns auf Dich!

Work Life Balance. Jobs bei Gedoplan

We are looking for you!

Lust bei GEDOPLAN mitzuarbeiten? Wir suchen immer Verstärkung – egal ob Entwickler, Dozent, Trainerberater oder für unser IT-Marketing! Schau doch einfach mal auf unsere Jobseiten! Wir freuen uns auf Dich!