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?
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
}
}