系统异常与应用异常的清晰解释

2022-09-01 07:28:31

JPA 规范区分系统异常和应用程序异常。我对这条线的确切位置有点困惑。我的猜测:

应用程序异常是代码使用的代码或库显式或隐式引发的异常。

  • 这是否包括所有异常、运行时和已检查,而不考虑源?

系统异常可能是持久性提供程序引发的异常。它当然包含 的所有子类。javax.persistence.PersistenceException

  • 提供程序代码引发的其他异常呢?
  • 其他 Java EE 库引发的异常呢?
  • 如果将异常包装在 ?EJBException

如何使用 ApplicationException 注释来影响行为?我从未见过它被使用过。


答案 1

当存在业务逻辑错误(而不是系统错误)时,应引发应用程序异常。

有一个重要的区别:应用程序异常不会自动导致事务回滚。客户端有机会在引发应用程序异常后进行恢复。

应用程序异常将发送到客户端,而无需重新打包为 EJBException。因此,您可以使用它们来报告验证错误或业务逻辑问题,它们将到达客户端。

这是否包括所有异常、运行时和已检查,而不考虑源?

不。默认情况下,应用程序异常是不扩展 RuntimeException 或 RemoteException 的异常。您可以更改此设置,如下所述。

如何使用 ApplicationException 注释来影响行为?

如果您希望事务自动回滚,则可以使用@ApplicationException(rollback=true)。

您还可以在 RuntimeException 和 RemoteException 的子类上使用注释,以避免包装为 EJBException,并定义它们的自动回滚行为。

其他 Java EE 库引发的异常呢?

它们将遵循相同的规则,但您可以使用 XML 描述符将第三方类声明为应用程序例外(带或不带自动回滚)。

提供程序代码引发的其他异常呢?

不确定,我认为您很少会看到来自提供程序代码的非系统错误(远程或运行时异常)。

如果将异常包装在 EJBException 中,是否有区别?

是的。这将影响您处理客户端代码中异常的方式。

(参考:Enterprise JavaBeans 3.0, Bill Burke, O'Reilly)

我希望它能有所帮助。


答案 2

我觉得,我必须补充这个非常清晰的描述,Mahesh Desai在Coderanch上给出的:

任何作为 Exception 的子类,但不是 RuntimeException 和 RemoteException 的子类的异常,都是应用程序异常。所有应用程序异常都是检查异常,因此,当我们调用方法中可以引发应用程序异常的另一个方法时,我们必须在调用方法的 throws 子句中声明它,或者在调用方法的正文中捕获它,或者两者兼而有之。

除 RemoteExceptions 之外,所有系统异常都是未选中的异常,用户无法处理它。