2

所以问题很简单:

我们正在使用带有 Primefaces 和 EJB 的 JSF 2.0 来处理我们的应用程序,但遇到了一个问题。我们有一个@SessionScopedbean 来存储我们所有的 bean @Stateful Session Beans

在一种情况下,(当我们没有处理来自 JPA 的一些异常时)并且有一个异常:

javax.persistence.PersistenceException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.2.0.v20110202-r8913): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "webuser_idwebuser_pk"
  Detail: Key (idwebuser)=(6) already exists.

它导致我们的一个@Stateful Session Bean. 因此,在刷新网站后,当 JSF 仍然正常工作时,在填写表单并尝试提交后,通过调用该 Bean 中的方法会出现异常:

javax.ejb.NoSuchObjectLocalException: The EJB does not exist. session-key: 22900a4d007e1f-6dcc714a-0

最有问题的是,我们必须重新启动并重新部署应用程序以使其在同一台计算机(或 Web 浏览器)上工作,因为 JSF 的@SessionScopedBean 以某种方式通过 cookie 或其他方式保存。

所以我猜的解决方案是强制销毁@SessionScoped该会话或以某种方式刷新会话,但实际上我不知道该怎么做。或者有什么更好的方法。

谢谢!

4

2 回答 2

6

为了解决这个问题,您需要了解 EJB 中应用程序异常和系统异常之间的区别。

这些大致分别对应于检查异常和运行时异常。

应用程序异常应该由您自己的代码处理,并且不会导致事务回滚或破坏 bean。系统异常具有相反的效果,会导致回滚和 EJB bean 的破坏。

后一种效果就是您所看到的。JPA 抛出未经检查的异常,从而成为系统异常,从而导致您的 SFSB 被破坏。JSF 和 CDI 托管的 bean 都参与了这个“系统异常”的事情,所以它们只会传播异常并保持活动状态。

您可能想要的是定义一个新的异常,您使用 @ApplicationException 进行注释,然后将其回滚属性设置为 true。在您的 SFSB 中捕获 JPA 异常,并使用您的自定义异常包装并重新抛出它。

于 2012-08-29T08:50:57.160 回答
-3

好的,所以我自己找到了答案。实际上我需要的是通过扩展 ActionListenerImpl 来处理 JSF 视图中的异常。

原文在这里: 原文

但是我所做的是通过使 HTTP 会话无效来扩展异常处理,这最终结束了@SessionScoped托管 Bean 的生命并导致重新注入 SSB。像这样:

private void gotoErrorPage(MethodExpression expression) {
        FacesContext context = FacesContext.getCurrentInstance();
        Application application = context.getApplication();

        HttpSession session = (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(false);
        if (session != null) {
            session.invalidate();
        }

        NavigationHandler navHandler = application.getNavigationHandler();
        navHandler.handleNavigation(context, null == expression ? null : expression.getExpressionString(), NAV_ERRORPAGE);
        context.renderResponse();
    }
于 2012-08-29T09:41:15.247 回答