I have a method that receives a JPA Entity
and its related EntityManager
as parameters. The Entity
instance is not created inside the class, and it might very well be shared by other classes (like GUIs and such).
The method starts a transaction, carries out some changes on the entity, and finally commits the transaction.
In case the commit fails, EntityTransaction.rollback()
is called: in accordance with JPA specifications, the entity is then detached from the manager.
In case of failure the application needs to discard the pending changes, restore the original values inside the entity e
and re-attach it to the EntityManager
, so that the various scattered references to the e
object would remain valid. The problem raises here: what I understood is that this is not a straightforward operation using the EntityManager
's APIs:
- calling
EntityManager.refresh(e)
is not possible sincee
is detached. - doing
e = EntityManager.merge(e)
would create a new instance fore
: all the other references to the originale
in the program at runtime would not be updated to the new instance. This is the main issue. - moreover (actually not quite sure about this),
EntityManager.merge(e)
would update the new managed instance's values with the values currently held bye
(i.e., the values that probably caused the commit to fail). Instead, what I need is to reset them.
Sample code:
public void method(EntityManager em, Entity e) {
EntityTransaction et = em.getTransaction();
et.begin();
...
// apply some modifications to the entity's fields
...
try {
et.commit();
} catch (Exception e) {
et.rollback();
// now that 'e' is detached from the EntityManager, how can I:
// - refresh 'e', discarding all pending changes
// - without instantiating a copy (i.e. without using merge())
// - reattach it
}
}
What is the best approach in this case?
e
have any changes, which are not commited to the database yet? – Uoooe
's state to be synchronized with the database row when passed as argument. @BobDalgleish: Thee
object itself maybe referenced by other (unknown) classes which may separately modify other fields of it in distinct transactions (not concurrent though). I was hoping some non complex reset & re-attach strategies existed. Your approach is useful too. – Max The Pax