Java OPenJPA::如何在引发异常时提交实体

Java OPenJPA::如何在引发异常时提交实体,java,jpa,java-ee-6,openjpa,Java,Jpa,Java Ee 6,Openjpa,在EJB项目中,对于特定的异常,我仍然希望持久化当前回滚的实体。在异常块中创建和刷新实体没有帮助。事务仍在回滚。 我试图从当前事务中分离实体,并将其持久化到新事务中。但这会导致“由另一个事务管理的实体”错误。 我怎样才能做到这一点 该项目基于JEE6和EJB3.1构建。持久性是OpenJPA的一部分。将这一部分用 boolean itWorked = true; try { // .. persistence operation which throws exception } catch

在EJB项目中,对于特定的异常,我仍然希望持久化当前回滚的实体。在异常块中创建和刷新实体没有帮助。事务仍在回滚。 我试图从当前事务中分离实体,并将其持久化到新事务中。但这会导致“由另一个事务管理的实体”错误。 我怎样才能做到这一点

该项目基于JEE6和EJB3.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)
}
确保您没有捕获一般异常,而只捕获特定异常(由于某些原因,这意味着持久化仍然有效)

第14.2.1节介绍了如何实现这一点:

Bean提供程序定义应用程序异常。被检查为异常的应用程序异常可以通过在bean的业务接口、无接口视图、主接口、组件接口和web服务端点的方法的throws子句中列出来定义。未检查异常的应用程序异常通过使用注释将其定义为应用程序异常 ApplicationException元数据注释,或在部署描述符中表示它 使用应用程序异常元素

应用程序异常不会自动将事务标记为回滚,除非ApplicationException注释应用于异常类,并使用回滚元素值true或 异常的应用程序异常部署描述符元素将回滚元素指定为true。[……]

在从企业Bean实例引发应用程序异常之前,Bean提供程序必须执行以下操作之一以确保数据完整性:

  • 确保实例处于这样的状态:客户端尝试继续和/或提交事务不会导致数据完整性丢失。例如,实例抛出一个应用程序异常,指示在实例执行任何数据库更新之前输入参数的值无效
  • 如果未指定应用程序异常导致事务回滚,请在引发应用程序异常之前,使用EJBContext.setRollbackOnly方法将事务标记为回滚。将事务标记为回滚将确保该事务永远不会提交
也就是说,如果希望在抛出异常时提交事务,则必须将该异常指定为应用程序异常


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

异常是否通常表示对象无法持久化?如果实体被分离,则它不会“由另一个事务管理”所以你显然把代码弄乱了。发布代码和异常,因为您无法提交已经回滚的内容。回滚是异常情况下的默认行为。我想显式地保留覆盖此默认行为的实体。谢谢Meriton。我的印象是,上面的选项只有在选中异常的情况下才可能实现,这是我们不希望在代码中包含的。我将尝试未检查的应用程序异常。这个答案很有帮助。谢谢