2012-03-20 46 views
3

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

回答

6

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

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

围绕这些例外没有什么魔法。从切赫上述调整的代码,
下面将只是工作:

支持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继承并标注有该@ApplicationExceptionrollback属性设置为true。

E.g.

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

    public MyException(Throwable cause) { 
     super(cause); 
    } 
} 

将您的EntityExistsException包装到您的EJB中,并将其抛出并捕获它。

我强烈建议你不要使用错误代码或布尔成功/失败作为结果。这是一个众所周知的反模式,并使您的代码难以置信的出错。

+0

谢谢你让我知道,我不知道这是如何工作。顺便说一句,这就是为什么我写了据我所知。 – 2012-03-20 20:33:36

2

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

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

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

是从类型UserException ...得到枚举理由例外...等

相关问题