I want to do below steps while already in active transaction
I have this
@Stateless
public class DBWorker {
public Result doWork(boolean isPreview) {
Result result;
if(isPreview) {
em.getTransaction().begin();
}
doSomeWork();
List<SomeEntity> resultOfDoSomeWork = em.createQuery(..).getResultList();
result = copyToNonEntity(resultOfDoSomeWork);
if(isPreview)
em.getTransaction().rollback();
return result;
}
}
But gives exception A JTA EntityManager cannot use getTransaction()
IllegalStateException:A JTA EntityManager cannot use getTransaction()
You have to annotate your EJB method with the @TransactionAttribute
Annotation.
In particular, you have to do something like this:
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public void myMethod() {
// do something
}
REQUIRES_NEW
indicates that a new transaction has to be started for the business method.
Pay attention to call the method to another EJB because if you call it from the same one the new transaction will not be created.
You can roll back the container-managed transaction:
@ApplicationException(rollback=true)
: setRollbackOnly
method of the EJBContext
interface: forces the container to rollback the transaction, also if there is no exception.For example:
Throwing a RuntimeException:
try {
// do something
} catch(SQLException e) {
throw new EJBException();
}
Throwing a custom Exception:
try {
// do something
} catch(SQLException e) {
throw new MyCustomException();
}
where MyCustomException class is something like:
@ApplicationException(rollback=true)
public class MyCustomException extends Exception {
// your custom methods
}
By invoking setRollbackOnly the method:
Context.setRollbackOnly();