Sammlungen werden im Allgemeinen durch Lazy Fetching, die meisten anderen Felder durch Eager Fetching gefetcht. Das ist der Grund dafür, dass beim Aufruf einer Person deren Adress-Eigenschaft ein Adress-Objekt enthält.
Es gibt aber noch ein weiteres Problem, selbst wenn man diese Änderungen vorgenommen hat: Man erhält eine Transient Object Exception bei einer Person. Das liegt daran, dass die savePerson-Methode nicht die Person managt, die ihr übergeben wurde, auch wenn sie durch EntityManager merge() persistent ist. merge() erzeugt ein neues gemanagtes Objekt, wenn der Methode eine neu erzeugte Instanz übergegeben wird, und kopiert Daten in dieses neue gemanagte Objekt, wohingegen persist() die Instanz, die ihr übergeben wird, zu einer gemanagten macht.
Das liegt am Lebenszyklus von Objekten: Wenn man ein Objekt mit new erzeugt, befindet es sich im Status new/transient. Wenn man es persistent macht, gelangt es für die Lebensdauer des EntityManager, in dem es persistent ist, in den gemanagten Status. Wenn dieser EntityManager geschlossen wird, wird die Instanz gelöst. Man kann die Instanz mit merge wieder einem anderen EntityManager zuordnen oder durch die find-Methode des EntityManager eine neue Kopie mit der ID des gelösten Objekts erhalten. Es gibt einen weiteren Status, removed, der eintritt, wenn das Objekt aus dem EntityManager bei anstehender Löschung entfernt wurde. Doch wozu sind diese verschiedenen Status gut? Dadurch wird die Vorstellung verabschiedet, man müsse DTOs (Data Transfer Objects) haben, Klassen, die als Behälter dienen, um zurückgeschickte Daten auf höhere Ebenen der Applikation zu bringen. Statt einer DTO- und einer persistent gemachten Klasse hat man jetzt nur eine persistent gemachte Klasse, die gelöst werden kann.
Im Beispiel-Code kann man savePerson() so ändern, dass persist() verwendet wird, und die nicht unähnliche Methode updatePerson() hinzufügen, die merge und updateAddress() verwendet, um eine Verbindung für Address durchzuführen. Jetzt kann der Code für die Zuordnung der Adresse von oben komplettiert werden:
Eine Person kann man von einer Adresse zu einer anderen durch updateAddress() verschieben, nachdem man die Person von den residents jeder Adresse entfernt oder zu ihr hinzugefügt hat. Das Verschieben sollte jedoch eine unteilbare Operation sein, daher verwendet man eine moveTo-Methode. Das beginnt mit einem Vorspann, mit dem man einen EntityManager und eine Transaction erhält:
Die find-Methode des EntityManager soll dazu verwendet werden, gemanagte Versionen der Einheiten zu bekommen:
Und wenn eine gemanagte Instanz aufgerufen wird, ist alles, was innerhalb der Transaktion daraus aufgerufen wird, ebenfalls gemanagt. Somit kann man folgendermaßen eine gemanagte Kopie der aktuellen Adresse erhalten:
Da man nun die gemanagte Version hat, kann man sie etwa so manipulieren:
Jetzt müssen diese Änderungen übergeben werden. Da nur die gemanagten Versionen eines aktuellen EntityManager und innerhalb einer Transaktion manipuliert wurden, muss jetzt nur noch die Transaktion übergeben werden, um die Änderungen persistent zu machen:
Neueste Kommentare
Noch keine Kommentare zu EJB Persistence mit Java Standard Edition (2. Teil)
Kommentar hinzufügenVielen Dank für Ihren Kommentar.
Ihr Kommentar wurde gespeichert und wartet auf Moderation.