即使EJB方法抛出异常,如何持久化JPA实体?

即使EJB方法抛出异常,如何持久化JPA实体?,jpa,jakarta-ee,ejb,java-ee-6,Jpa,Jakarta Ee,Ejb,Java Ee 6,我有一个EJB,它的方法(除其他外)持久化JPA实体。如果方法抛出错误,事务将回滚,实体不会持久化 但是,我不希望该实体被持久化,而不管EJB方法中可能出现的任何异常 如果需要的话,我正在使用WebSphere7.0、EJB3.0、JPA1.0(WAS中的OpenJPA)、DB2 我尝试在EJB上设置@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED);这样,即使并没有异常,实体也不会持久化。我自己也尝试提交事务(em.get

我有一个EJB,它的方法(除其他外)持久化JPA实体。如果方法抛出错误,事务将回滚,实体不会持久化

但是,我不希望该实体被持久化,而不管EJB方法中可能出现的任何异常

如果需要的话,我正在使用WebSphere7.0、EJB3.0、JPA1.0(WAS中的OpenJPA)、DB2


我尝试在EJB上设置
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
;这样,即使并没有异常,实体也不会持久化。我自己也尝试提交事务(em.getTransaction().commit()),但getTransaction()抛出异常(因为事务由容器管理)。

我不是EJB专家,但我已经处理JPA和事务几天了

我最近回答了另一个问题,关于实体如何驻留在上下文中,以及如何在JavaEE应用程序中工作,上下文与JTA事务相关联

单击可查看此答案的详细信息。我认为,为了理解你所描述的问题的本质,理解上下文是如何工作的是很有用的

如果您不提供事务支持,那么从容器的角度来看,没有什么可持久的,因此,您对上下文的更改是暂时的

您还必须考虑,一旦发生异常,您的上下文将变得无效,并且其中的实体将被分离。(有一些例外,比如NoResultException)

因此,从那时起,如果您想要提交一些东西,您需要一个新的JTA事务,以及一个新的JPA上下文,以便能够提交对数据库的更改

正如我所说,我不是EJB方面的专家,但是如果您的方法由于异常而失败,并且您仍然希望通过重新调用该方法来重试该事务,那么您可以在每次调用该方法时强制创建一个新的事务,这样,您就可以创建一个新的JPA上下文

另一方面,如果您希望对要持久化的实体进行修改,不管该方法中的异常如何,那么您可能需要考虑将正在更新实体的代码移动到一个新的EJB方法中,该新EJB方法被定义为每次调用它时启动一个新的事务(TraceActudiTeType。 当第二个内部方法完成时,您对事务的处理将自动刷新到数据库中,而不管您的外部方法是否失败

基本上,您将为您的实体提供一个新的上下文,并将这种上下文链接到一个新的事务,该事务的作用域是在内部方法完成时提交

据我所知,EJB容器中的自然行为是ever方法加入已经存在的事务,在我看来,这是您可能想要阻止的


另一个备选方案:如果您想使用不同的事务支持来控制上下文,那么您可能需要考虑提供基于资源的持久化单元,并且可以手动实例化您的实体管理器并按照您的意愿控制事务范围。但老实说,这听起来不是个好主意,至少在您描述的问题的背景下不是。

我不是EJB专家,但我已经处理JPA和事务好几天了

我最近回答了另一个问题,关于实体如何驻留在上下文中,以及如何在JavaEE应用程序中工作,上下文与JTA事务相关联

单击可查看此答案的详细信息。我认为,为了理解你所描述的问题的本质,理解上下文是如何工作的是很有用的

如果您不提供事务支持,那么从容器的角度来看,没有什么可持久的,因此,您对上下文的更改是暂时的

您还必须考虑,一旦发生异常,您的上下文将变得无效,并且其中的实体将被分离。(有一些例外,比如NoResultException)

因此,从那时起,如果您想要提交一些东西,您需要一个新的JTA事务,以及一个新的JPA上下文,以便能够提交对数据库的更改

正如我所说,我不是EJB方面的专家,但是如果您的方法由于异常而失败,并且您仍然希望通过重新调用该方法来重试该事务,那么您可以在每次调用该方法时强制创建一个新的事务,这样,您就可以创建一个新的JPA上下文

另一方面,如果您希望对要持久化的实体进行修改,不管该方法中的异常如何,那么您可能需要考虑将正在更新实体的代码移动到一个新的EJB方法中,该新EJB方法被定义为每次调用它时启动一个新的事务(TraceActudiTeType。 当第二个内部方法完成时,您对事务的处理将自动刷新到数据库中,而不管您的外部方法是否失败

基本上,您将为您的实体提供一个新的上下文,并将这种上下文链接到一个新的事务,该事务的作用域是在内部方法完成时提交

据我所知,EJB容器中的自然行为是ever方法加入已经存在的事务,在我看来,这是您可能想要阻止的

另一个备选方案:如果您想使用不同的事务支持来控制上下文,那么您可能需要考虑提供基于资源的持久化单元,并且可以手动实例化您的实体管理器并按照您的意愿控制事务范围。但老实说,这是真的

@Stateless
@TransactionManagement(TransactionManagementType.BEAN)
public class MyEJB {
  @PersistenceContext(unitName="...")
  private EntityManager _em;
  @Resource
  private UserTransaction _utx;

  public void myEJBMethod() {
    _utx.begin();
    // Use _em
    _utx.commit();
    // Do other work that might throw an exception.
  }
}