Ein Persistence Context verwaltet Entities und kontrolliert ihren Lebenszyklus.
Man unterscheidet zwei Arten von Persistence Context:
–Transaction-scoped Persistence Context
–Extended Persistence Context
•Mit EntityManagerFactory.createEntityManager() bekommt man den Extended Persistence Context.
–createEntityManager() liefert den Application-Managed Entity Manager.
•Der Persistence Context beginnt, wenn der Application-Managed Entity Manager erzeugt wird und endet erst dann, wenn der Entity-Manager geschlossen wird.
•Werden Entities geladen, so bleiben sie so lange im Extended Persistence Context, bis der der Kontext geschlossen oder alle Entities ausdrücklich gelöscht werden.
–Entities bleiben also sehr lange „manged“ und nur dann „detached“, wenn der Entity-Manager geschlossen wird.
•Der Transaction Persistence Context ist der übliche Persistence Context eines „Container-Managed Entity Managers“, der also über den Container injiziert wird.
@PersistenceContext EntityManager em;
•Der EntityManager erzeugt pro Transaktionen einen neuen Persistence Context.
–Der Persistence Context endet bei einem Commit oder Rollback der Transaktion.
•Innerhalb der Transaktion werden die zum Beispiel über find() oder Query geladenen Entites zu managed Entities.
•Da nach der Transaktion der Persistence Context endet, werden die dort verwalteten Entities detached.
•Da der Transaction Persistence Context pro Transaktion aufgebaut wird, ist die Anzahl der verwalteten Objekte relativ klein.
•Der Extended Persistence Context ist oft deutlich länger und kann nach einer Zeit sehr viele Objekte aufnehmen.
–Damit kann das zu einem Speicherproblem werden.
•Um beim Extended Persistence Context kein Speicherproblem zu bekommen gibt es unterschiedliche Strategien:
–Von Zeit zu Zeit clear() vom EntityManager aufrufen. Das detached Objetkte.
–Auf das passende Lazy-Load achten.
–Weniger Objekte laden: Bei unachtsamem Design werden oft viel zu viele Objekte geladen.
•Besonders Gib-Mir-Alles-Ausdrücke wie „select o from Entity o“ sind gefährlich, da die Anzahl der Objekte groß sein kann, obwohl nur ein kleiner Teil der Objekte wirklich benötigt wird.
–Eine Paginierung kann hier sinnvoller sein um nur das zu laden, was zum Beispiel sichtbar ist.
•Einzelne Entities lassen sich nicht aus dem Entity-Manger entfernen (detachen).
–Bei Hibernate oder anderen Implementierungen funktioniert das, bei JPA standardmäßig nicht.
•Aber andersherum gibt es eine Lösung.
–Also alles freigeben, bis auf ausgewählte Objekte.
•Gibt es einen Verweis auf eine Entity-Objekt vom Persistence Context aus und von außen, und wird dann clear() den Persistence Context löschen, wird der Garbage-Collector das Objekt natürlich nicht freigeben.
–Das losgelöste Entity-Objekt kann später mit merge() wieder in den Persistence Context gesetzt werden.