在JSF + EJB应用程序中捕获数据库异常

max*_*a72 3 oracle ejb jpa java-ee jsf-2

我正在使用带有JSF2和EJB无状态的Glassfish 3.1来查询和编写Oracle DB.用户想要在此Web应用程序中填充的表具有主键.当用户尝试添加新记录时,将调用调用em.persist的ejb方法.现在,如果用户尝试添加具有已使用的主键值的记录,则在EJB中出现异常.我想向用户弹出一条消息,指出数据库中发生了错误,但我无法弄清楚JSF托管bean如何捕获EJB异常.有什么办法吗?

Arj*_*jms 7

EJB具有系统异常和应用程序异常的概念.

运行时异常,例如EntityExistsException系统异常.这些将导致任何事务被回滚并导致EJB实例bean被丢弃(销毁).最重要的是你的问题,他们将被包裹在一个EJBException.

抓住这些例外并没有什么魔力.调整上面
的Petr代码,以下内容将起作用:

支持豆:

@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);
     }         
}
Run Code Online (Sandbox Code Playgroud)

EJB:

private EntityManager em;

public void save(Entity e) {    
    em.persist(e);    
}
Run Code Online (Sandbox Code Playgroud)

请注意,您可以检索异常的原因以查看是否为异常EntityExistsException(为简洁起见,上面省略).

由于您可能不需要为此情况销毁EJB实例,因此更好的模式是定义自己的继承自a的异常,RuntimeException@ApplicationException使用rollback属性设置为true进行批注.

例如

@ApplicationException(rollback = true)
public class MyException extends RuntimeException {

    public MyException(Throwable cause) {
        super(cause);
    }
}
Run Code Online (Sandbox Code Playgroud)

将您EntityExistsException的EJB 包装到此异常中并抛出并捕获它.

我强烈建议您不要使用错误代码或布尔成功/失败.这是一个众所周知的反模式,使您的代码容易出错.