【问题标题】:catch DB exception in JSF+EJB application在 JSF+EJB 应用程序中捕获 DB 异常
【发布时间】:2012-04-04 17:24:43
【问题描述】:

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

【问题讨论】:

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


    【解决方案1】:

    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 属性设置为真的。

    例如

    @ApplicationException(rollback = true)
    public class MyException extends RuntimeException {
    
        public MyException(Throwable cause) {
            super(cause);
        }
    }
    

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

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

    【讨论】:

    • 感谢您告诉我,我不确定这是如何工作的。顺便说一句,这就是我据我所知写的原因。
    【解决方案2】:

    您可以创建自定义异常类。假设UserException 带有可能的异常选项的枚举值。

    在您的 EJB 中,您可以将您的方法定义为可抛出的。如果需要抛出异常。

    在您的 JSF-SiteBean 中,您只需要使用简单的 try/catch。

    是来自 UserException 类型的异常...获取枚举原因...等

    【讨论】:

      猜你喜欢
      • 2015-03-31
      • 2011-10-13
      • 1970-01-01
      • 1970-01-01
      • 2011-09-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-26
      相关资源
      最近更新 更多