OPenJPA::抛出异常时如何提交实体

OPenJPA: : How to commit entities when an exception is thrown

在一个EJB项目中,对于一个特定的异常,我想仍然保留当前回滚的实体。在异常块中创建和刷新实体无济于事。事务仍然被回滚。 我试图从当前事务中分离实体并将其保存在新事务中。但这会导致 "entity managed by another transaction " 错误。 我怎样才能做到这一点?

该项目是基于 JEE6 和 EJB 3.1 构建的。持久性与 OpenJPA 有关。

将那个位包装在

boolean itWorked = true;
try {
   // .. persistence operation which throws exception
} catch (YourFavouriteException yfe) {
  itWorked = false;
}
if (!itWorked) {
  // try it again (the definition of insanity)
}

确保你没有捕获一般异常,而只捕获你的特定异常(出于某种原因,这意味着持久化仍然有效)

EJB 3.1 spec 在第 14.2.1 节中描述了如何完成此操作:

The Bean Provider defines application exceptions. Application exceptions that are checked exceptions may be defined as such by being listed in the throws clauses of the methods of the bean’s business interface, no-interface view, home interface, component interface, and web service endpoint. An application exception that is an unchecked exception is defined as an application exception by annotating it with the ApplicationException metadata annotation, or denoting it in the deployment descriptor with the application-exception element

An application exception does not automatically result in marking the transaction for rollback unless the ApplicationException annotation is applied to the exception class and is specified with the rollback element value true or the application-exception deployment descriptor element for the exception specifies the rollback element as true. [...]

The Bean Provider must do one of the following to ensure data integrity before throwing an application exception from an enterprise bean instance:

  • Ensure that the instance is in a state such that a client’s attempt to continue and/or commit the transaction does not result in loss of data integrity. For example, the instance throws an application exception indicating that the value of an input parameter was invalid before the instance performed any database updates.
  • If the application exception is not specified to cause transaction rollback, mark the transaction for rollback using the EJBContext.setRollbackOnly method before throwing the application exception. Marking the transaction for rollback will ensure that the transaction can never commit.

也就是说,如果您希望在抛出异常时提交事务,则必须将该异常指定为应用程序异常

或者您可以启动一个单独的事务,但由于 JEE 不支持嵌套事务,这只有在前一个事务完成后才有可能。