所以这个问题很简单:
我们使用JSF 2.0 Primefaces和EJB来处理我们的应用程序,我们已经遇到了一个问题。 我们有一个@SessionScoped
中,我们存储所有我们的豆@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仍然正常工作,填写表格后,并试图将其提交,通过从豆有异常调用一个方法后:
javax.ejb.NoSuchObjectLocalException: The EJB does not exist. session-key: 22900a4d007e1f-6dcc714a-0
什么是最有问题的,我们必须重新启动,并重新部署应用程序,使其在同一台计算机(或网络浏览器)工作,因为JSF的@SessionScoped
豆以某种方式通过cookie什么的保持。
所以我猜这个解决办法是迫使该的destuction @SessionScoped
或以某种方式刷新会话,但实际上我不知道怎么做。 或者,这将是一个更好的办法。
谢谢!
为了解决这个问题,你需要知道关于EJB应用程序和系统异常的区别。
这些大致分别对应于检查和运行时异常。
应用程序异常都应该通过自己的代码进行处理,并不会导致一个事务回滚或豆的破坏。 系统异常有相反的效果,会导致回滚和EJB bean的破坏。
后者的效果是你所看到的。 JPA抛出unchecked异常,这因此成为系统异常,这进而引起你的SFSB被破坏。 JSF也不CDI管理的bean参与到这个“系统异常”的事情,所以他们只会传播异常,并会活下去。
你可能想要的是定义你注释与@ApplicationException然后将其回滚属性为true的新的异常。 您SFSB内赶上JPA例外,敷,并与您的自定义异常重新抛出。
好了,所以我发现我自己的答案。 其实我所需要的是通过扩展ActionListenerImpl来处理JSF视图例外。
原来的文章是在这里: 原创
但是我做了什么是扩展例外与,最终,结束了生命的HTTP会话失效处理@SessionScoped
托管Bean和含铅,以办学团体的回注。 像这样:
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();
}
文章来源: Handling 'The EJB does not exist' or 'Cannot load from BACKUPSTORE FOR Key'