A JTA EntityManager cannot use getTransaction()

auser picture auser · Jun 9, 2012 · Viewed 45.9k times · Source

How do I have the following code in my non-ejb application. The code works.

@Override
public void saveItems(Collection<T> items) {
    synchronized (em) {
        EntityTransaction tx = em.getTransaction();
        try {
            tx.begin();
            for (T item : items) {
                saveItem_((Class<T>) null, item);
            }
            tx.commit();
        } finally {
            if (tx.isActive()) {
                tx.rollback();
            }
        }
    }
}

In a new application I'm using EJB3 + JSF and would like to re-use the library containing the code above. My peristence unit for the new application looks like this:

  <persistence-unit name="myApp" transaction-type="JTA">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <jta-data-source>MySQLConnection</jta-data-source>
  </persistence-unit>

My new application throw an exception when it hits this line:

    EntityTransaction tx = em.getTransaction();

the exception is:

A JTA EntityManager cannot use getTransaction()

Which is clear enough. The question is how would I convert my code to have the transactions managed by the container. Presumably my bean methods need to be annotated appropriately... The question is how?

Answer

Nayan Wadekar picture Nayan Wadekar · Jun 10, 2012

EntityTransaction is used with entity manager of type resource local. If you want to use JTA, then have to use UserTransaction interface.

From Documentation : EntityTransaction - Interface used to control transactions on resource-local entity managers. The EntityManager.getTransaction() method returns the EntityTransaction interface.


Edit: Added pseudo code.

@Resource
private SessionContext sessionContext;

void execute(){

UserTransaction userTxn = sessionContext.getUserTransaction();

try{

 userTxn.begin();
 /**
  *  do-something
  */
 userTxn.commit();

  } catch(Throwable e){
   userTxn.rollback(); //-- Include this in try-catch 
  }
}