EJB 3.0 异常处理

13

EJB规范中的一句话:

如果Bean方法遇到系统异常或错误,它应该只是将错误从Bean方法传播到容器(即,Bean方法不必捕获异常)。

但我不理解这是什么意思。这是否意味着我不应该捕获所有类型的异常(例如尝试捕获 Exception 类),并将其重新抛出为我的应用程序异常?

以下是更清晰的示例:

public void beanMethod throws MyApplicationException {
  try {
    // do something
  } catch (Exception e) {
     throw new MyApplicationException(e); // Should I do it like this? 
  }
}

这是否仅适用于EJB参考实现开发人员(容器开发人员),而不是EJB开发人员:如果是后者,则容器不应将系统异常传播到我的业务方法,因此我的catch(Exception e)块永远不会捕获任何系统异常?

2个回答

16

有更多种类的异常:

  • 系统异常(RuntimeExceptions例如空指针异常NullPointerException)
  • 业务异常(自定义异常,继承Exception但不是RuntimeException,例如NotEnoughMoneyOnYourAccountException)
  • 错误(例如内存溢出OutOfMemoryError)

通常情况下,您应该捕获业务异常。但是,如果您想在客户端处理它,当然也可以将其抛出到客户端。默认情况下,EJB容器不会回滚您的事务,如果您抛出BusinessException,但是您可以通过以下方式注释您的Exception来更改此行为:

@ApplicationException(rollback = true)
public class NotEnoughMoneyOnYourAccountException extends Exception {

如果您的程序抛出RuntimeException异常,它将被发送到客户端并包装为RemoteException,您的事务将被回滚。这些异常比业务异常更少见,因此通常我们不在EJB端捕获它们。

错误是最不被期望的,它们甚至可以关闭JVM,通常我们不会捕获它们,因为通常无法在程序中处理它们。


你建议我在 EJB 方法中根本不要使用 try-catch 块? - WelcomeTo
也许你想将一个非运行时异常包装成自己的异常。例如,SQLException --> MyBusinessException。 - Donato Szilagyi
好的,谢谢。如果我的EJB使用DAO层,并且DAO层可以抛出RuntimeException,我能否在Ejb业务方法中捕获我的DAO特定异常并将其重新抛出为MyBusinessException?如果我不捕获它,那么容器将假定我的DaoException是系统异常,并因此销毁ejb实例(当发生系统异常时,ejb实例被销毁)。但我不想因SQL代码中的某些错误而失去ejb实例。 - WelcomeTo
} catch (SQLException e) { throw new NotEnoughMoneyOnYourAccountException(e.getMessage(), e.getCause()); } - Donato Szilagyi

0
我不知道您从哪里得到这个提示以及上下文是什么,但它似乎意味着bean方法本身不应进行任何异常处理,只需抛出任何收到的异常。该行为通常通过在throws子句中添加方法体可能引发的异常(例如变量输入等环境/随机因素)来实现,其中现在是MyApplicationException
直接由方法代码错误引起的异常(而不是方法调用中的错误)通常不需要被正确处理,因为它们应该通过测试和调试排除。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接