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

时间:2012-03-20 08:30:51

标签: oracle java-ee jpa jsf-2 ejb

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

2 个答案:

答案 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。