Аннотация @Temporal не работает при использовании с тестами @Transactional JUnit.

У меня есть простые операции CRUD с Spring Boot и Oracle 11g. Мой класс Entity выглядит так:

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());
}

Последний log.info генерирует исключение NullPointerException при запуске с аннотацией @Transactional, но в противном случае работает нормально, и БД заполняется ожидаемыми значениями.

Так ведет себя @Transactional или Hibernate не вставляет никакого значения для дат в транзакционные JUnits?


person shrinathM    schedule 22.06.2017    source источник
comment
Ваша транзакция не зафиксирована, поэтому Temporal не работает. Вы должны зафиксировать транзакцию. Попробуйте метод flush из репозитория.   -  person ByeBye    schedule 22.06.2017


Ответы (1)


Поскольку вы используете аннотацию @Transactional в своем классе, все ваши изменения не фиксируются в БД. @CreationTimestamp и `@Temporal(TemporalType.TIMESTAMP)' не будут работать, пока изменения не будут зафиксированы.

Что вы можете сделать:

Не используйте @Transactional в функциональном тесте с использованием БД. Если вы удалили аннотацию, ваш метод не будет откатываться после завершения метода, поэтому вам нужно создать метод @After с очисткой вашего материала, созданного тестами:

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

Второй вариант — изменить метод сохранения на saveAndFlush. Также вы можете сделать это после того, как вы сохранили сущность, вызвав метод entityRepository.flush(), но здесь вам нужно еще раз получить свою сущность из репозитория:

entityRepository.save(entity);
entityRepository.flush();
Entity savedEntity = entityRepository.findOne(id);
person ByeBye    schedule 22.06.2017