首页 > 解决方案 > @DataJpaTest 使用存储库保存实体,无法使用 JdbcTemplate 检索数据

问题描述

我正在从 spring-boot 1.5.x 迁移到 2.0.4,并注意到 @DataJpaTest 的一个有趣的案例/行为

我有一个测试

@ExtendWith(SpringExtension.class)
@DataJpaTest
public class SomeTest {

    @Autowired
    private SomeRepository repository;
    @Autowired
    private JdbcTemplate template;


    @Test
    public void save() {

        String number = "123";

        SomeEntity entity = SomeEntity.builder()
                .number(number)
                //some attributes here
                .build();

        repository.save(entity);


//that line fails because SELECT returns nothing back
        Map<String, Object> result = template.queryForMap("select id, version from some_entity where number=?", number);

}

上述测试失败,因为模板没有返回任何内容。我什至看不到日志中触发的 INSERT 语句。但是对于 1.5.x 的旧版本的 spring-boot,我可以看到 INSERT 被触发并且测试通过了。

但是升级版本的有趣之处在于,如果我在一切正常之前添加一行repository.findAll(不是repository.findById(id)-> 那一行不会有帮助),repository.save(entity)并且在日志中,我可以看到并触发 INSERT 语句。

有人可以帮助我了解发生了什么以及它是如何工作的。为什么实体没有被持久化?以及为什么repository.findAll如此特别以至于可以持久化数据。

谢谢。

标签: javaspringspring-bootspring-data

解决方案


这是因为 findAll 方法触发了从内存(持久性上下文)到数据库的所有更改的刷新。

你可以在我的屏幕上看到这一切发生的地方: 在此处输入图像描述

JpaRepository 中也有对应的方法:

https://docs.spring.io/spring-data/jpa/docs/current/api/org/springframework/data/jpa/repository/JpaRepository.html#flush--
可用于立即刷新更改。

此外,您可以使用 saveAndFlush 方法:

https://docs.spring.io/spring-data/jpa/docs/current/api/org/springframework/data/jpa/repository/JpaRepository.html#saveAndFlush-S-


推荐阅读