我正在使用带有JSF2和EJB无状态的Glassfish 3.1来查询和编写Oracle DB。用户想要在此Web应用程序中填充的表具有主键。当用户尝试添加新记录时,将调用调用em.persist的ejb方法。现在,如果用户尝试添加具有已使用的主键值的记录,则在EJB中出现异常。 我想向用户弹出一条消息,指出数据库中发生了错误,但我无法弄清楚JSF托管bean如何捕获EJB异常。 有什么办法吗?
答案 0 :(得分:7)
EJB具有系统异常和应用程序异常的概念。
运行时异常(如EntityExistsException
)是系统异常。这些将导致任何事务被回滚并导致EJB实例bean被丢弃(销毁)。最重要的是,对于您的问题,它们将包含在EJBException
。
没有任何魔法可以捕捉到这些异常。调整上面的Petr代码,
以下内容将起作用:
支持bean:
@EJB
private DAOBean daoBean;
public void savePerson(Entity e) {
try {
daoBean.save(e);
} catch (EJBException e) {
FacesMessage message = new FacesMessage("entity is already exists.");
FacesContext.getCurrentInstance.addMessage(null, message);
}
}
EJB:
private EntityManager em;
public void save(Entity e) {
em.persist(e);
}
请注意,您可以检索异常的原因以查看是否为EntityExistsException
(为简洁起见,在上面省略)。
由于您可能不需要为此情况销毁EJB实例,因此更好的模式是定义自己的异常,该异常继承自RuntimeException
并使用@ApplicationException
注释rollback
1}}属性设置为true。
E.g。
@ApplicationException(rollback = true)
public class MyException extends RuntimeException {
public MyException(Throwable cause) {
super(cause);
}
}
将EJB中的EntityExistsException
包装到此异常中并抛出并捕获它。
我强烈建议您 NOT 使用错误代码或布尔成功/失败。这是一个众所周知的反模式,使您的代码容易出错。
答案 1 :(得分:2)
您可以创建自定义异常类。假设UserException
具有可能的异常选项的枚举值。
在EJB中,您可以将方法定义为throwable。如果你需要抛出异常。
在你的JSF-SiteBean中,你只需要使用一个简单的try / catch。
UserException类型的异常... get enum reason ... etc。