代码之家  ›  专栏  ›  技术社区  ›  qwazer

Spring数据JPA存储库上invoke count()方法时的JPA缓存行为

  •  0
  • qwazer  · 技术社区  · 6 年前

    为了检查表中的行数,我使用了side JDBCTemplate。

    org.springframework.data.repository.CrudRepository#save(S) 不会生效。SQL insert in未执行,表中的行数未增加。

    org.springframework.data.repository.CrudRepository#count 之后 save(S)

    我猜这是JPA缓存的行为,但它是如何工作的呢?

    弹簧靴代码:

    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class ErrorMessageEntityRepositoryTest {
    
        @Autowired
        private ErrorMessageEntityRepository errorMessageEntityRepository;
        @Autowired
        private JdbcTemplate jdbcTemplate;
    
        @Test
        @Transactional
        public void save() {
            ErrorMessageEntity errorMessageEntity = aDefaultErrorMessageEntity().withUuid(null).build();
            assertTrue(TestTransaction.isActive());
            int sizeBefore= JdbcTestUtils.countRowsInTable(jdbcTemplate, "error_message");
            ErrorMessageEntity saved = errorMessageEntityRepository.save(errorMessageEntity);
            errorMessageEntityRepository.count(); // [!!!!] if comment this line test will fail
            int sizeAfter= JdbcTestUtils.countRowsInTable(jdbcTemplate, "error_message");
            Assert.assertEquals(sizeBefore+1, sizeAfter);
        }
    

    实体:

    @Entity(name = "error_message")
    public class ErrorMessageEntity {
    
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        private UUID uuid;
        @NotNull
        private String details;
    

    存储库:

    public interface ErrorMessageEntityRepository extends CrudRepository<ErrorMessageEntity, UUID>
    
    2 回复  |  直到 6 年前
        1
  •  4
  •   Jens Schauder    6 年前

    你是对的,这是JPA工作方式的结果。 JPA尽量延迟SQL语句的执行。

    当保存新实例时,这意味着只有在需要插入才能获取实体的id时,它才会执行插入。

    1. 显式调用 flush EntityManager 您可以直接这样做,也可以通过JPA使用Spring数据 saveAndFlush

    第三是你看到的效果。

    请注意,由于您可以配置很多这样的东西,所以细节要复杂一些。 As usual, Vlad Mihalcea has written an excellent post about it .

        2
  •  0
  •   Miller Cy Chan    6 年前

    为了使测试数据不污染数据库,在使用Spring test的单元测试时,事务默认回滚,即@Rollback默认为true。如果要在不回滚的情况下测试数据,可以设置@Rollback(value=false)。如果您使用的是MySQL数据库,在设置了自动回滚之后,如果发现事务仍然没有回滚,可以检查数据库引擎是否为Innodb,因为MyISAM、Memory等其他数据库引擎都不支持事务。

    推荐文章