Monday, July 4, 2011

JPA joinTransaction Problem

When using JPA as your ORM in Java Web applications, you likely use transactions. As transaction-type you specify "RESOURCE_LOCAL" in your persistence.xml.

Suppose we have these two methods:
 public Object create(Object o){
em.getTransaction().begin();
em.persist(o);
em.getTransaction().commit();
return o;
}
and

public void delete(Object entity){
em.getTransaction().begin();
em.remove(entity);
em.getTransaction().commit();
}




The problem which occured when calling multiple times a new transaction was:

"joinTransaction has been called on a resource-local EntityManager"

That means, somehow a joined Transaction should be used, although we didn't configure JTA.
The source of this problem is, that we would call multiple times new transactions, which won't be executed after each other, but in parallel.

The solution was to set all methods in which a transaction is used to synchronized.
This leads to exact processing of the transactions in correct order.

 public synchronized Object create(Object o){
em.getTransaction().begin();
em.persist(o);
em.getTransaction().commit();
return o;
}
and

public synchronized void delete(Object entity){
em.getTransaction().begin();
em.remove(entity);
em.getTransaction().commit();
}

3 comments: