我正在使用带有 JSF2 和 EJB 无状态的 Glassfish 3.1 来查询和编写 Oracle 数据库。用户想要在此 Web 应用程序中填充的表有一个主键。当用户尝试添加新记录时,调用 em.persist 的 ejb 方法被调用。现在,如果用户尝试添加具有已使用主键值的记录,我会在 EJB 中遇到异常。 我想向用户弹出一条消息,指出数据库中发生了错误,但我无法弄清楚 JSF 托管 bean 如何捕获 EJB 异常。 有什么办法吗?
最佳答案
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
属性设置为 true。
例如
@ApplicationException(rollback = true)
public class MyException extends RuntimeException {
public MyException(Throwable cause) {
super(cause);
}
}
将您的 EJB 中的 EntityExistsException
包装到此异常中并抛出并捕获它。
我强烈建议您不要因此使用错误代码或 bool 值成功/失败。这是一种众所周知的反模式,使您的代码容易出错。
关于oracle - 在 JSF+EJB 应用程序中捕获 DB 异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9783505/