Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Jakarta ee 在JavaEE无状态会话bean中,为什么SessionContext负责回滚事务,而不是EntityManager?_Jakarta Ee_Jboss_Hibernate Entitymanager - Fatal编程技术网

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

Jakarta ee 在JavaEE无状态会话bean中,为什么SessionContext负责回滚事务,而不是EntityManager?,jakarta-ee,jboss,hibernate-entitymanager,Jakarta Ee,Jboss,Hibernate Entitymanager,对于我(JavaEE开发新手),我认为容器管理的EntityManager负责回滚失败的事务,而不是SessionContext实例。假设以下场景 @Stateless public class MySessionBean implements MySessionBeanRemoteInterface { @PersistenceContext(unitName="MYPu") private EntityManager em; @Resource privat

对于我(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;
         }
    }

}

为什么实体经理不对此负责?为什么要使用SessionContext?

因为您告诉容器通过JTA(
transaction type=“JTA”
)管理事务,而不是JPA(
transaction type=“RESOURCE\u LOCAL”
)。JTA反过来由EJB容器管理。因此,
SessionContext
的角色就出现在这里

但让我烦恼的是,您正在抑制异常并返回
null
。在业务服务方法中最好不要这样做。您最好让异常消失,而不是返回
null
。EJB容器在任何异常情况下都会自动执行回滚。去掉EJB中的
try-catch
returnnull
,让EJB的客户机自己处理异常

例如

试试看{
CreateSourser(用户名,代表);
}捕获(持久异常e){
showSomeGlobalErrorMessage(如getMessage());
}
或者,更好的是,让它进一步进入底层容器。例如,如果它实际上是一个servlet容器:


javax.persistence.PersistenceException
/WEB-INF/errorpages/db-fail.xhtml
或者MVC框架甚至有一个可定制的全局异常处理程序。至少,JSF允许这样的机会,您可以全局设置faces消息,而无需在调用服务方法的托管bean方法的所有地方重复
try-catch

另见:

伙计,这就像从名人那里得到签名一样!我觉得你的回答很有帮助。但是,我想知道,如果EntityManager对我负责持久化、合并、删除等,它不负责回滚的原因是什么(可能我在这里遗漏了一个概念,或者没有真正理解EntityManager的预期功能)回滚似乎是EntityManager的功能之一。这是因为回滚事务需要来自会话的数据(由于容器管理的事务)吗?是的,但是当委托给JTA时,EJB会接管它,这样您就不必担心回滚了。这样,您的代码就更简单了。或者您真的打算在每个服务方法中都使用try-catch回滚吗?这就破坏了EJB+JTA的工作。另请参阅第二个“也请参阅”链接(也许还有其中的“也请参阅”链接)。我并不打算这样做。然而,我上面作为示例给出的代码的结构在我正在开发的现有应用程序中。我个人会按照你说的做,而不是返回null,我会在方法上添加一个抛出,并将异常抛出。感谢您的指导(以及过去几个月我一直在阅读的所有教程)。欢迎:)您不必添加
抛出
,也不必自己抛出异常。当查询返回异常结果时,JPA将执行此操作。除非JPA没有根据您的业务需求抛出异常。当然,您可以随意抛出自定义异常,只要它带有注释。EJB随后也将透明地执行回滚。