@Temporal 注释在与@Transactional JUnit 测试一起使用时不起作用

@Temporal annotation does not work when used with @Transactional JUnit tests

我有一个简单的 CRUD 操作 Spring Boot 和 Oracle 11g 我的实体 class 看起来像:

public class Entity{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int entity_id;
...
@CreationTimestamp
@Column(name = "creation_date", columnDefinition="ON UPDATE CURRENT_TIMESTAMP")
@Temporal(TemporalType.TIMESTAMP)
private Date creation_date;

...//setters and getters
}

我的 JUnit 看起来像

@RunWith(SpringRunner.class)
@SpringBootTest
@Transactional
public class EntityTests {
Logger log = Logger.getAnonymousLogger();

@Autowired
private EntityRepository  entityRepository;

@Test
public void addEntity(){
    Entity entity= new Entity();
    entity.setFirst_name("Jhon");
    entity.setLast_name("David");
    Entity savedEntity = entityRepository.save(entity);
    log.info(savedEntity.toString());
    Assert.assertEquals(entity, savedEntity);
    //log.info(savedEntity.getCreation_date().toString());
}

当 运行 带有 @Transactional 注释时,最后一个 log.info 抛出 NullPointerException,但在其他情况下工作正常,DB 会填充预期值。

这是@Transactional 的行为方式还是 Hibernate 不在事务性 JUnit 中为日期插入任何值?

因为您在 class 上使用了 @Transactional 注释,所以您所做的所有更改都不会提交到数据库中。 @CreationTimestamp 和“@Temporal(TemporalType.TIMESTAMP)”在提交更改之前将不起作用。

你能做什么:

不要在使用 DB 的功能测试中使用 @Transactional。如果您删除了注释,您的方法将不会在方法结束后回滚,因此您必须创建 @After 方法并清理测试创建的内容:

@After
public void cleanUp() {
    entityRepository.deleteAll();
}

第二个选项是将您的保存方法更改为saveAndFlush。您也可以在通过调用 entityRepository.flush() 方法保存实体后执行此操作,但在这里您必须再次从存储库中获取您的实体:

entityRepository.save(entity);
entityRepository.flush();
Entity savedEntity = entityRepository.findOne(id);