Dienstag, 20. März 2012

Persistieren mit JPA: persist(), merge(), remove(), clear(), close() oder doch flush()?

Welche JPA - Methode sollte in welcher Situation genutzte werden?
JPA bietet einige Methoden an, um mit dem PersistenzManager zu arbeiten:
  • persists()
  • merge()
  • remove()
  • flush()
  • close()
Was passiert beim persist() / flush() / close?
Beim persist() wird die transiente Entität in den Persistenkontext aufgenommen, d.h. die Entität hat eine Verbindung zum EntityManager erhalten. Diese Entität erhält aber nicht sofort eine Repräsentation in der Datenbank!
Wird beispielsweise die Transaktion zurückgerollt, aufgrund eine SQL-Fehlers oder mittels eines expliziten
rollbacks, dann wird die transiente Entität oder Änderungen an anderen Entitäten nicht in der Datenbank abgespeichert:
EntityManagerFactory emf = Persistence.createEntityManagerFactory("persistence");
EntityManager em = emf.createEntityManager();

...
em.getTransaction().rollback();
...

Möchte man nun innerhalb einer Transaktion an bestimmten Stellen die Synchronisation mit der Datenbank auslösen, dient flush().
Was passiert bei detachten Entitäten beim flush-Aufruf? Nichts.
Was passiert mit persistent Entities, die mit transienten Entities verbunden sind? IllegalStateException
Was passiert mit einer persistent Entity, die mit einer detached Entity verbunden ist? Die Beziehung zur detached Entity wird persistiert, wenn die persistent Entity Besitzer dieser Beziehung ist.

Überlicherweise wird bei Beendigung der Transaktion die gemachten Änderungen an den Entitäten und die neu angelegten persistenten Entitäten in der Datenbank vom JPA-Provider gespeichert.

Bei einem close() wird der EntityManager geschlossen und wie bei clear() werden alle Entitäten vom EntiyManager gelöst.
Diese Entitäten gehen in den Zustand detached über und werden so nicht mehr mit der Datenbank synchronisiert. Um genau diese wieder zu ermöglichen gibt es die Methode merge().
Hiermit können detached-Entitäten wieder in den Persistenzkontext überführt werden.
Dabei werden die Attributwerte der zu mergenden Entität in die bestehende persistente Entität hineinkopiert.
Fall zur detached Entität in der Session keine persistente Entität befindet, dann wird
versucht die betreffende Entität zu laden oder sie wird angelegt.

Eine Entität wird mit remove() aus dem Persistenzkontext genommen und bei Transaktionsende aus der Datenbank gelöscht. Wird auf eine gelöscht markierte Entität merge() aufgerufen, so wird eine IllegalArgumentException geworfen.






Keine Kommentare:

Kommentar veröffentlichen