在JavaEE无状态会话bean中,为什么SessionContext负责滚动事务而不是EntityManager?

时间:2015-06-03 16:30:46

标签: java-ee jboss hibernate-entitymanager

对于我(对JavaEE开发不熟悉的人),我认为容器管理的EntityManager将负责回滚失败的事务而不是SessionContext实例。假设以下场景......

@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;
         }
    }

}

为什么EntityManager不对此负责?为什么会使用SessionContext?

1 个答案:

答案 0 :(得分:1)

因为您告诉容器通过JTA(transaction-type="JTA")管理事务,而不是JPA(transaction-type="RESOURCE_LOCAL")。 JTA又由EJB容器管理。因此SessionContext在这里的作用。

但令我困扰的是,你是在抑制异常并返回null。您最好不要在商业服务方法中这样做。您最好让异常转而不是返回null。 EJB容器将在任何特殊情况下自动执行回滚。摆脱EJB中的try-catchreturn null,让EJB的客户端处理异常本身。

E.g。

try {
    mySessionBean.createSOUser(userName, rep);
} catch (PersistenceException e) {
    showSomeGlobalErrorMessage(e.getMessage());
}

或者,更好的是,让它进一步转到底层容器。例如。如果它实际上是一个servlet容器:

<error-page>
    <exception-type>javax.persistence.PersistenceException</exception-type>
    <location>/WEB-INF/errorpages/db-fail.xhtml</location>
</error-page>

或许有问题的MVC框架甚至还有一个可自定义的全局异常处理程序。至少,JSF允许这个机会,然后你可以全局设置一个faces消息,而不需要在调用服务方法的托管bean方法中的所有地方重复try-catch

另见: