Spring数据JPA+;Hibernate:永远不会到达事务方法内的catch块

Spring数据JPA+;Hibernate:永远不会到达事务方法内的catch块,spring,jpa,try-catch,spring-data-jpa,transactional,Spring,Jpa,Try Catch,Spring Data Jpa,Transactional,在我们的SpringDataJPA+Hibernate应用程序中,有多种方法在同一事务中具有多个JPA操作——下面是其中一种Spring服务方法的代码/配置 @Transactional(rollbackFor=MyAppException.class) public void updateCustomerprofile(String customerKey) throws MyAppException{ try{ CustomerId customerIdObj = custo

在我们的SpringDataJPA+Hibernate应用程序中,有多种方法在同一事务中具有多个JPA操作——下面是其中一种Spring服务方法的代码/配置

@Transactional(rollbackFor=MyAppException.class)
public void updateCustomerprofile(String customerKey) throws MyAppException{
    try{
    CustomerId customerIdObj = customerIdRepository.findOne(customerKey);
    customerIdObj.setCreatedUser("<loggedin-user>");
     // more logic here
    customerIdObj = customerIdRepository.save(customerIdObj);
    }catch(DataAccessException dae){
        //this catch block is never reached even if there is an exception while saving because of JPA flusheing at the end of transaction
        throw new MyAppException(dae);
    }

}
@Transactional(rollboor=MyAppException.class)
public void updateCustomerprofile(字符串customerKey)引发MyAppException{
试一试{
CustomerId customerIdObj=customerIDepository.findOne(customerKey);
customerIdObj.setCreatedUser(“”);
//这里有更多的逻辑
customerIdObj=customeridepository.save(customerIdObj);
}捕获(DataAccessException dae){
//即使在保存时由于事务结束时JPA溢出而出现异常,也永远不会到达此捕获块
抛出新的MyAppException(dae);
}
}
据观察,即使保存记录时抛出异常,执行也永远不会到达catch块,这是因为JPA在事务结束时刷新

这个挡块应该放在什么地方

我们应该在web层(bean)上捕获DataAccessException吗

如果是这样的话,我们是否将数据层依赖关系带到web层

如果我必须将DataAccessException包装到特定于应用程序的异常中,我该怎么做


请建议。

在catch块内添加一个
entityManager.flush()
,或者在@Transactional注释的方法周围移动catch块

原因是实体管理器通常可以自由决定何时将数据写入数据库(即异常发生的时间点)。通常,对数据库的写入已完成

  • 在“选择”查询之前
  • 当显式调用entityManager.flush()时
  • 提交事务时

因此,解决方案是:确保实体管理器将(非法)数据写入try块内的数据库。

在catch块内添加
entityManager.flush()
,或者在@Transactional annotated方法周围移动catch块

原因是实体管理器通常可以自由决定何时将数据写入数据库(即异常发生的时间点)。通常,对数据库的写入已完成

  • 在“选择”查询之前
  • 当显式调用entityManager.flush()时
  • 提交事务时

因此,解决方案是:确保实体管理器将(非法)数据写入try块内的数据库。

在catch块内添加
entityManager.flush()
,或者在@Transactional annotated方法周围移动catch块

原因是实体管理器通常可以自由决定何时将数据写入数据库(即异常发生的时间点)。通常,对数据库的写入已完成

  • 在“选择”查询之前
  • 当显式调用entityManager.flush()时
  • 提交事务时

因此,解决方案是:确保实体管理器将(非法)数据写入try块内的数据库。

在catch块内添加
entityManager.flush()
,或者在@Transactional annotated方法周围移动catch块

原因是实体管理器通常可以自由决定何时将数据写入数据库(即异常发生的时间点)。通常,对数据库的写入已完成

  • 在“选择”查询之前
  • 当显式调用entityManager.flush()时
  • 提交事务时

因此,解决方案是:确保实体管理器将(非法)数据写入try块中的数据库。

这里的问题是,异常不会在代码中引发,而是在容器提交事务时引发(另请参见)。要避免使用bean管理的事务,您可以:

  • 通过
    EntityManager.flush()同步持久性上下文
  • 使用带有
    @AroundInvoke
    注释的EJB拦截器,该注释开始、提交和回滚事务(类似于BMT),或者
  • 使用
    @TransactionAttribute(REQUIRES_NEW)
    将应该引发异常的代码包装到方法中

另请参见,其中进一步解释了有关
需要新的
方法的一些详细信息。

这里的问题是,异常不是在代码中引发的,而是在容器提交事务时引发的(另请参见)。要避免使用bean管理的事务,您可以:

  • 通过
    EntityManager.flush()同步持久性上下文
  • 使用带有
    @AroundInvoke
    注释的EJB拦截器,该注释开始、提交和回滚事务(类似于BMT),或者
  • 使用
    @TransactionAttribute(REQUIRES_NEW)
    将应该引发异常的代码包装到方法中

另请参见,其中进一步解释了有关
需要新的
方法的一些详细信息。

这里的问题是,异常不是在代码中引发的,而是在容器提交事务时引发的(另请参见)。要避免使用bean管理的事务,您可以:

  • 通过
    EntityManager.flush()同步持久性上下文
  • 使用带有
    @AroundInvoke
    注释的EJB拦截器,该注释开始、提交和回滚事务(类似于BMT),或者
  • 使用
    @TransactionAttribute(REQUIRES_NEW)
    将应该引发异常的代码包装到方法中

另请参见,其中进一步解释了有关
需要新方法的一些详细信息。

这里的问题是