在JSF + EJB应用程序中捕获DB异常 [英] catch DB exception in JSF+EJB application

查看:198
本文介绍了在JSF + EJB应用程序中捕获DB异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

解决方案

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

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



。调整上面的Petr代码,

以下将会正常工作:



备份bean:

  @EJB 
私人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) ;
}
}

包含您的 EntityExistsException 在您的EJB中进入此异常并抛出并捕获它。



我强烈建议您使用错误代码或布尔值成功/失败。这是一个众所周知的反模式,使您的代码难以置信的错误。


I'm using Glassfish 3.1 with JSF2 and EJB stateless to query and write an Oracle DB. The table the user wants to populate in this web application has a primary key. When the user tries to add a new record the ejb method invoking em.persist is called. Now, if the user tries to add a record that has an already used primary key value, I got an exception in the EJB. I would like to pop up a message to the user indicating that an error in the database occurred but I can't figure out how the JSF managed bean could catch the EJB exception. Is there any way?

解决方案

EJB has the concept of system exceptions and application exceptions.

Runtime exceptions, like EntityExistsException are system exceptions. These will among others cause any transaction to be rolled-ed back and cause the EJB instance bean to be discarded (destroyed). Most importantly for your problem, they will be wrapped in an EJBException.

There is no magic surrounding catching these exceptions. Adjusting the code from Petr above,
the following will just work:

Backing 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);    
}

Note that you can retrieve the cause of the exception to see if was an EntityExistsException or not (omitted above for brevity).

Since you probably have no need to destroy your EJB instance for this case, a better pattern is to define your own exception that inherits from a RuntimeException and is annotated with the @ApplicationException with the rollback attribute set to true.

E.g.

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

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

Wrap your EntityExistsException in your EJB into this exception and throw and catch it.

I strongly advise you NOT to use error codes or boolean success/failure as a result. This is a well-known anti pattern and makes your code incredible error prone.

这篇关于在JSF + EJB应用程序中捕获DB异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆