Spring Data Jpa - 当@transactional存在时,存储库不会抛出异常

时间:2014-02-23 17:40:42

标签: spring hibernate jpa spring-data-jpa

我有以下课程:

public interface GarageRepository extends PagingAndSortingRepository<Garage, Integer> {}

public class GarageBO {
  private GarageRepository garageRepository;

  public void updateGarage(Garage garage) {
    try {
      garageRepository.save(garage);
    } catch (Exception e) {
      throw BoozinaExceptions.getCodeException(garage, e);
    }
  }
}

public class GarageFacade implements GarageService {
  private GarageBO garageBO;

  @Transactional
  public void updateGarage(Garage garage) {
    garageBO.updateGarage(garage);
  }
}

假设我正在尝试更新车库并且抛出了一个独特的违规行为 当我使用@Transactional注释从GarageFacade调用updateGarage时,garageRepository不会抛出任何异常。
当我在没有@Transactional注释的情况下调用相同的方法时,garageRepository抛出唯一的违例异常,现在我可以使用BoozinaExceptions.getCodeException(garage, e)转换异常;

发生这种情况是因为当我有@Transactional注释时,Spring jpa数据执行提交时将抛出异常。这是在GarageBO.updateGarage执行后发生的吗?

但我需要转换唯一的违规行为。我怎么能这样做? 提交后如何处理spring异常然后转换为我的异常?

1 个答案:

答案 0 :(得分:4)

您描述的是预期的行为。在方法结束后提交事务,提交导致唯一约束违规。

@Transactional添加到服务方法会使事务在调用提交事务的服务方法之后结束。删除它会在调用存储库方法后进行事务提交。

另外,为什么你有BO一个Facade和一个存储库?!基本上BO和Facade是相同的恕我直言。

要解决您的问题,请GarageRepository延长JpaRepository而不是PagingAndSortingRepository并调用saveAndFlush方法而不是save。这将执行sql(不提交事务)并触发约束违例异常。

另一种解决方案是在BO创建和Aspect中执行try / catch,而不是在转换中执行。每次需要时都可以节省编写try / catch的代码。