无法在Spring Data CRUD方法上强制实施Propagation.MANDATORY

时间:2017-12-05 14:00:30

标签: java spring spring-data transactional propagation

这有什么原因吗?

我多年来一直在使用Spring数据,但我认为我之前从未对其中一种开箱即用的CRUD方法进行过单元测试。

为什么以下接口定义对CRUD方法的事务实现没有影响?

@Repository
@Transactional(propagation = Propagation.MANDATORY)
public interface MyRepository extends JpaRepository<MyEntity, Long> {

    Stream<MyEntity> findMyEntityByStatusEquals(Status status);
}

如果我从测试方法中调用myRepository.save(new MyEntity()),没有我的测试被包装在事务中,它就会成功。

但是,如果我致电myRepository.findMyEntityByStatusEquals("MY_STATUS"),它就会失败,说明它需要包含在交易中。

后一种情况我预计,前一种情况会让我感到害怕,因为我似乎无法强制它成为现有交易的一部分。

:: Edit :: @Transactional置于界面顶部对以前标记为@Transactional的Spring Data CRUD方法没有影响。我总是认为在这些接口上指定时它也是一个覆盖。

1 个答案:

答案 0 :(得分:2)

正如documentation here

所述
  

默认情况下,存储库实例上的CRUD方法是事务性的。对于   读取操作事务配置readOnly标志已设置   为true,所有其他人都配置了一个简单的@Transactional,以便   默认事务配置适用。

@Transactional将Propagation.REQUIRED作为其默认传播类型,因此当您调用save方法时,新事务才会开始。

如果你想在 buily-in CRUD方法中强制传播.MANDATORY,你必须覆盖这些方法,即

@Repository
@Transactional(propagation = Propagation.MANDATORY)
public interface MyRepository extends JpaRepository<MyEntity, Long> {

    Stream<MyEntity> findMyEntityByStatusEquals(Status status);

    @Transactional(propagation = Propagation.MANDATORY)
    public <MyEntity> MyEntity save(MyEntity entity) {
      super.save(entity);
    }
}

希望这会有所帮助