Тестирование с пометкой Spring с @Transactional удобно, но не так, как будет выполняться ваш производственный код.Аннотация @Transactional запустит транзакцию до запуска тестового метода и откатит ее после завершения метода теста.
Пока фиксации предшествует сброс, откат не выполняется, поэтому ручнойflush - это механизм безопасности, обеспечивающий преобразование всех изменений сущностей в операторы SQL.
Более подходящим вариантом было бы явное отображение границ транзакции следующим образом:
@Test
public void testRootObjects() {
final Company newCompany = new Company();
newCompany.setName("TV Company");
final Long companyId = transactionTemplate.execute(new TransactionCallback<Long>() {
@Override
public Long doInTransaction(TransactionStatus transactionStatus) {
entityManager.persist(newCompany);
return newCompany.getId();
}
});
Company detachedCompany = transactionTemplate.execute(new TransactionCallback<Company>() {
@Override
public Company doInTransaction(TransactionStatus transactionStatus) {
Company attachedCompany = entityManager.find(Company.class, companyId);
assertEquals(newCompany, attachedCompany);
assertEquals(newCompany.hashCode(), attachedCompany.hashCode());
return attachedCompany;
}
});
assertEquals(newCompany, detachedCompany);
assertEquals(newCompany.hashCode(), detachedCompany.hashCode());
}
* TransactionTemplate зафиксирует ваш код, поэтому нет необходимости в ручных сбросах.
Если вы вызываете методы сервиса @Transactional через их интерфейс, вам вообще не понадобится транзакция транзакции, так как вы вызываете прокси Spring, который будет вызывать TransactionInterceptor (при условии, что вы указали Spring, чтобы он знал о аннотациях транзакций:) и поэтому транзакции будут начаты / совершены от вашего имени.