To me (someone who is new to JavaEE development), I would think that a container managed EntityManager would be responsible for rolling back failed transactions and not a SessionContext instance. Suppose the following scenario...
@Stateless
public class MySessionBean implements MySessionBeanRemoteInterface {
@PersistenceContext(unitName="MYPu")
private EntityManager em;
@Resource
private SessionContext sctx;
@Override
public StackOverFlowUser createSOUser(String userName, int rep) {
try {
StackOverFlowUser su = new StackOverFlowUser();
su.setUserName(stackOverflowName);
su.setRep(rep);
su.setIsBalusC(userName.equals("BalusC");
su.setIsTheJonSkeet(userName.equals("jon skeet"));
return em.merge(su);
} catch (Exception e) {
//sctx.setRollbackOnly();
return null;
}
}
}
Why wouldn't the EntityManager be responsible for this? Why would SessionContext be used?
Because you told the container to manage transactions via JTA (transaction-type="JTA"
), not JPA (transaction-type="RESOURCE_LOCAL"
). JTA is in turn managed by EJB container. Hence the role of the SessionContext
here.
But what bothers me, you're suppressing the exception and returning null
. You'd better not do that in business service methods. You'd better let the exception go instead of returning null
. The EJB container will in any exceptional case automatically perform the rollback. Get rid of the try-catch
and return null
in EJB and just have the EJB's client deal with the exception itself.
E.g.
try {
mySessionBean.createSOUser(userName, rep);
} catch (PersistenceException e) {
showSomeGlobalErrorMessage(e.getMessage());
}
Or, even better, just let it further go to the underlying container. E.g. if it's actually a servlet container:
<error-page>
<exception-type>javax.persistence.PersistenceException</exception-type>
<location>/WEB-INF/errorpages/db-fail.xhtml</location>
</error-page>
Or perhaps the MVC framework in question has even a customizable global exception handler for that. At least, JSF allows this opportunity, you could then globally set a faces message without the need to repeat the try-catch
over all place in managed bean methods calling a service method.