使用@Transactional时未检索数据库默认字段

时间:2019-03-07 16:05:55

标签: spring spring-boot spring-data-jpa h2 spring-transactions

我有以下简单的实体FileRegistry:

@Getter
@Setter
@Entity
@ToString
@Table(name = "file_store")
public class FileRegistry {

   @Id
   private String name;

  /**
   * Creation timestamp of the registry
   * This value is automatically set by database, so setter method
   * has been disabled
   */
   @Setter(AccessLevel.NONE)
   @Column(insertable = false, updatable = false)
   private LocalDateTime creationDate;
}

以下FileRepository DAO:

@Repository
public interface FileRepository extends JpaRepository<FileRegistry, String> { }

和以下Spring Boot测试:

@SpringBootTest(classes=PersistTestConfig.class, properties = { "spring.config.name=application,db"})
@ActiveProfiles("test")
@Transactional
public class FileRepositoryTest {

@Autowired
FileRepository fileRepository;

@Test
void insertFileTest() {
    assertNotNull(fileRepository, "Error initializing File repository");

    // Check registry before insertion
    List<FileRegistry> allFiles = fileRepository.findAll();
    assertNotNull(allFiles, "Error retrieving files from registry");
    assertThat(allFiles.size(), is(0));

    // Insert file
    FileRegistry fileRegistry = new FileRegistry();
    fileRegistry.setName("Test");

    fileRepository.save(fileRegistry);

    // Check that the insertion was successful
    allFiles = fileRepository.findAll();
    assertNotNull(allFiles, "Error retrieving files from registry");
    assertThat(allFiles.size(), is(1));
    assertEquals("File registry name mismatch", "Test", allFiles.get(0).getName());

    System.out.println(allFiles.get(0));
  }
} 

持久性配置类定义如下:

@Configuration
@EnableAutoConfiguration
@EnableTransactionManagement
@EnableJpaRepositories    
public class PersistTestConfig {
}

H2中定义的表file_store为:

    CREATE TABLE file_store (name VARCHAR NOT NULL, creation_date TIMESTAMP(3) DEFAULT NOW() NOT NULL, CONSTRAINT file_store_pk PRIMARY KEY (name));

一切正常,除了当我在测试级别使用@Transactional时(主要是受益于回滚,即每个测试中的db cleanup),为creationDate字段获取了空值:

FileRegistry(name=Test, creationDate=null)

当我从测试类中删除@Transactional时,获取的值包含H2计算的日期:

FileRegistry(name=Test, creationDate=2019-03-07T17:08:13.392)

我尝试刷新并手动合并实例,但无济于事。老实说,现在我对@Transactional的实际工作方式有些迷茫,实际上,在阅读文档并检查代码后,对底层JpaRepository实现(SimpleJpaRepository)进行了注释为@Transactional(readOnly = true)

在此问题上的一些帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

好,知道了。

只需发出刷新entityManager.refresh(allFiles.get(0));就可以解决此问题。

我还在实体@Generated(INSERT)字段中使用了Hibernate的creationDate特定的annotation进行了测试,而且效果也很好。

通过这种方式,我最终决定放弃使用Spring Data的JpaAuditing功能,并使用@CreatedDate注释对字段进行注释来填充值,而不是依赖于数据库日期(顺便说一句,生产) -wise,您可能不应该依赖数据库时间。对我来说,这种感觉更多,比方说,“正确”而富有弹性的做事方式。