A JTA EntityManager cannot use getTransaction()
ejb-3.0, java, persistence
Solution
`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
}
}
Problem
How can I use 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?