Am 14. September 2017 haben wir eine überarbeitete Fassung unserer Datenschutzrichtlinie veröffentlicht. Wenn Sie video2brain.com weiterhin nutzen, erklären Sie sich mit diesem überarbeiteten Dokument einverstanden. Bitte lesen Sie es deshalb sorgfältig durch.

Java EE 7 Grundkurs

Lebenszyklus von Entitäten

LinkedIn Learning kostenlos und unverbindlich testen!

Jetzt testen Alle Abonnements anzeigen
Entitäten besitzen in der Java EE einen Lebenszyklus, wobei Probleme hinsichtlich des JPA-Kontexts auftreten. Dabei begleitet die Spezifikation den Lebenszyklus von Entitäten durch verschiedene Methoden des Entity Managers.

Transkript

Wenn Sie mit der JPA arbeiten, ist es sehr notwendig, dass Sie ein wenig über den Lebenszyklus der Entitäten kennen und wissen. Wir werden genau dieses in diesem Video besprechen. Wir werden klären, welche Lebenszykluszustände es gibt, Und wie wir die Beans von einem Lebenszykluszustand in den anderen bekommen. Grundsätzlich ist es so, das Entitäten einen Lebenszyklus besitzen. Und zwar wechseln sie zwischen den Zuständen Transient, Persistent und Detatched hin und her. Was diese Zustände bedeuten, werden wir nun klären. Der Zustand Persistent bedeutet, dass die Bean, also die Entität in der Datenbank gespeichert ist, und vom EntityManager auch verwaltet wird, also ihm bekannt ist. Der Zustand Transient bedeutet, die Bean wird nicht von einem EntityManager verwaltet, und befindet sich auch nicht in der Datenbank. Das ist zum Beispiel der Fall, wenn ich so eine Bean anlege und sie noch nicht gespeichert habe. Oder aber, wenn ich eine Bean gelöscht habe, sie aber immer noch als Referenz in meiner Applikation benutze. Und der Zustand Detached besagt, dass die Bean zwar nicht von einem EntityManager verwaltet wird, sich aber in der Datenbank befindet. Es ist wichtig, diese Lebenszykluszustände zu kennen. Wir werden diese Lebenszykluszustände mit EntityManager-Operationen begleiten müssen. Uns wird nichts anderes übrigbleiben, denn wenn wir mit EJBs arbeiten ist es so, dass der EntityManager-Kontext immer ganz schnell weg ist. Nämlich sobald die entsprechende Methode, die wir aufgerufen haben, auf der EJB verlassen worden ist. Dann werden die Daten serialisiert und übertragen und serialisierte Daten haben keinen EntityManager-Kontext mehr. Und sobald dieser EntityManager nicht mehr existiert, das bedeutet, die Instanz ist verworfen worden, oder es fand eine Serialisierung oder ähnliche Sachen statt, sind die Beans automatisch detached. Das heißt, sie haben schlichtweg keinen EntityManager-Kontext mehr. Und das bedeutet für uns, wir müssen sie auf irgendeine Art und Weise wieder in den Kontext zurückholen. Dafür gibt es zwei Methoden, merge oder refresh. Beide existieren auf Ebene der EntityManager-Instanz. Die beiden Methoden unterscheiden sich. Generell ist es notwendig, dass wir Beans, die detached sind, wieder in den Kontext holen. Der EntityManager gibt dafür die beiden Möglichkeiten.. merge lädt die Bean aus der Datenbank, und überschreibt ihren Inhalt mit den Änderungen, die wir vorgenommen haben. Also quasi mit den Änderungen des Objektes, was wir in diese Methode reingeben. Das bedeutet, dass unsere Änderungen, die wir vorgenommen haben, die Änderungen in der Datenbank überschreiben. refresh funktioniert genau andersrum. Bei refresh werden die Änderungen, die wir vorgenommen haben in unserer Bean, die wir als Parameter in diese Methode reingeben, überschrieben, und zwar mit dem Inhalt in der Datenbank. Also, merge behält unsere Daten bei und speichert sie, refresh verwirft unsere Änderungen und überschreibt sie mit den originalen Daten aus der Datenbank. Den Lebenszyklus einer Bean können wir über sogenannte Das sind Methoden, die mit einer speziellen Annotation versehen sind. Davon gibt es einige, un wann immer ein bestimmtes Lebenszyklusereignis eintritt werden diese Methoden dann aufgerufen. Es gibt folgende EntityListener. PostLoad, also eine Methode die mit der Annotation PostLoad versehen ist. Eine derartige Methode wird ausgeführt, nachdem die Bean geladen und geupdatet worden ist. PrePersist. Methoden die mit dieser Annotation versehen sind, werden ausgeführt, bevor eine Speicheroperation stattfindet. PostPersist. Diese Methode wird dann ausgeführt, nachdem eine Speicheroperation stattfindet. PreUpdate wird ausgeführt, bevor in der Datenbank ein SQL-Updatestatement stattfindet. PostUpdate wird ausgeführt, nachdem ein SQL-Updatestatement stattgefunden hat. Und PreRemove wird ausgeführt, bevor eine Bean gelöscht wird. Das gleiche gilt analog für PostRemove nur wird diese Methode dann eben aufgerufen, nachdem die Bean gelöscht worden ist. Lassen Sie uns einmal schauen, wie wir dies in der Praxis umsetzen können. In dieser Webapplikation werden einige, in der Datenbank gespeicherte Bücher dargestellt. Wir haben zwei Operationen definiert: Löschen und Ändern. Beide Operationen werden intern begleitet und ausgeführt. Sie sind umgesetzt in der Klasse "BookHandler". Die Klasse "BookHandler" stellt entsprechende Methoden bereit, nämlich "delete" und "update". Die "delete"-Methode wird beim Klick auf den Löschen-Button ausgeführt. Und hier ist es so, dass wir uns von dem "BookManager", also der Komponente, die die Daten tatsächlich verwaltet, ein Buch holen und dieses Buch dann löschen. Die Methode "update" ist jetzt nicht sonderlich aufwendig implementiert. Deren Zweck ist es jetzt nicht, sonderlich große Änderugnen vorzunehmen sondern sie manipuliert lediglich das Erscheinungsjahr eines Buches. Anschließed wird dieses Buch wieder in der Datenbank gespeichert. In der Klasse "BookManager" haben wir die entsprechenden Implementierungen drin. Zum einen gibt es hier die Methode "updateBook", die auf dem EntityManager das Buch updated. Dazu rufen wir lediglich die Methode "merge" auf. Die Methode "deleteBook", die wir ebenfalls ausführen, die ruft die Methode "remove" des EntityManagers auf. Schauen wir uns einfach einmal an, wie diese Applikation funktioniert. Zunächst testen wir die Ändern-Funktionalität. Achten Sie auf das Jahr. Dieses ändert sich, das heißt, die Funktionalität funktioniert schon mal. Nu möchten wir ein Buch löschen. Lassen Sie uns schauen, wie dies funktioniert. Oh, das funktioniert nicht. Wenn wir uns die Fehlermeldung anschauen, dann sehen wir hier ganz deutlich, was passiert ist. Wir können eine, als detachd markierte Instanz nicht entfernen. Das ist seltsam, denn im "BookHandler" rufen wir ja hier ein Buch ab und übergeben es danach wieder an den Manager um es zu löschen. Warum das so ist, ist bereits vorhin erklärt worden. der "BookManager" ist eine EJB-Komponente. und zwar eine stateless session-Bean. Das Konzept einer stateless session-Bean besagt, dass diese Bean, beziehungsweise die darin enthaltenen Variablen und Referenzierungen, entfernt werden und gelöscht werden, nachdem eine Methode durchlaufen worden ist. Das heißt, wenn ich die Methode "getBook" aufrufe, die mir eine Buch-Instanz zurückgibt, dann wird die EntityManager-Instanz die mit dieser Methode assoziiert ist, anschließend verworfen. Hier im "BookHandler" rufen wir zunächst die Methode "getBook" auf. Das bedeutet, wir lassen uns ein Buch geben. Dieses Buch ist nun nachdem wir wieder in der aufrufenden Methode sind, aber nicht mehr unter JPA verwaltet. Dennoch übergeben wir es an die Methode "deleteBook" und in dieser Methode wird nun einfach die "remove"-Methode aufgerufen. Und das funktioniert eben nicht. Ich kann nicht auf einem EntityManager-Kontext mit einer als detached markierten Instanz löschen. Um dieses Problem zu umgehen gibt es zwei Ansätze. Zum einen könnte ich in der "deleteBook"-Methode das Buch noch einmal laden lassen, beziehungsweise das Buch updaten lassen. Dafür haben wir ja "merge" und "refresh". Die andere Methode ist, die die ich in der Implementierung darüber implementiert habe. Und zwar rufe ich mir hier in dieser Methode nun das Buch ab. Und zwar rufe ich die lokal liegende "getBook"-Methode ab. die auf dem aktuellen EntityManager-Kontext die "find"-Methode aufruft. Da der Aufruf von einer Methode der stateless session-Bean zur anderen Methode der stateless session-Bean funktioniert, ist es so, dass hier immer noch dieselbe EntityManager-Instanz im Einsatz ist. Und das bedeutet, das hier referenzierte Buch kann ich dann auch entfernen. Das müssen Sie beachten. Sobald Sie also die stateless session-Bean verlassen, ist auch der EntityManager futsch. Und das bedeutet für Sie, Sie müssen sich einen Umweg einfallen lassen, den Sie gehen können, um beispielsweise Komponenten wieder in den Kontext zurückzubekommen. Lassen Sie uns den "BookHandler" so abändern, dass dieser nunmehr die richtige Methode verwendet. Zu diesem Zweck löschen wir einfach den Code, den wir bereits haben und rufen die andere Implementierung der "deleteBook"-Methode auf. Indem wir einfach nur die ID des zu löschenden Buches reinübergeben. Nachdem wir die Applikation nun neu deployed haben, - das dauert wieder einige Sekunden - können wir nun die Funktionalität testen. So, welches Buch wollen wir löschen? Ich bin für das Testbuch. Dieses Buch ist erfolgreich gelöscht worden. Die Funktionalität ist nunmehr gegeben. Achten Sie also stets darauf, dass Sie, wenn Sie mit einem Persistence-Kontext, also einem EntityManager arbeiten, sicherstellen, dass Sie wissen, in welchem Kontext Sie sich gerade befinden. Nochmal als Faustregel: Sobald Sie eine stateless session-Bean verlassen, ist auch der EntityManager futsch. In diesem Video haben wir uns ein wenig mit dem Lebenszyklus von Komponenten und Entitäten im JPA-Umfeld auseinandergesetzt. Wir haben ebenfalls ein Problem aufgeworfen und gelöst, nämlich das Verhalten, wenn wir über verteilte Komponenten, und das sind ja stateless session-Beans, reden. Hier ist es wichtig zu wissen, dass sobald eine Serialisierung oder eine Rückgabe aus der stateless session-Bean an eine aufrufende Komponente stattgefunden hat, der EntityManager nicht mehr existiert. Er wird erst beim nächsten Aufruf neu injiziert und dann ist es eine andere Instanz. Dieses Verhalten müssen Sie sich merken.

Java EE 7 Grundkurs

Lernen Sie die Grundlagen der Programmierung mit Java EE 7 verstehen und anwenden.

6 Std. 4 min (44 Videos)
Derzeit sind keine Feedbacks vorhanden...
 

Dieser Online-Kurs ist als Download und als Streaming-Video verfügbar. Die gute Nachricht: Sie müssen sich nicht entscheiden - sobald Sie das Training erwerben, erhalten Sie Zugang zu beiden Optionen!

Der Download ermöglicht Ihnen die Offline-Nutzung des Trainings und bietet die Vorteile einer benutzerfreundlichen Abspielumgebung. Wenn Sie an verschiedenen Computern arbeiten, oder nicht den ganzen Kurs auf einmal herunterladen möchten, loggen Sie sich auf dieser Seite ein, um alle Videos des Trainings als Streaming-Video anzusehen.

Wir hoffen, dass Sie viel Freude und Erfolg mit diesem Video-Training haben werden. Falls Sie irgendwelche Fragen haben, zögern Sie nicht uns zu kontaktieren!