Аннотировать тесты Spring с помощью @Transactional удобно, но это не то, как будет выполняться ваш производственный код. Аннотация @Transactional запустит транзакцию до запуска вашего тестового метода и откатит ее, когда тестовый метод завершится.
В то время как фиксации предшествует сброс, откату — нет, поэтому сброс вручную — это механизм безопасности, гарантирующий, что все изменения Entity будут переведены в операторы 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 через их интерфейс, вам вообще не понадобится transactionTemplate, так как вы вызываете прокси-сервер Spring, который будет вызывать TransactionInterceptor (при условии, что вы указали Spring знать об аннотациях транзакций: ), и поэтому транзакции будут запущено/совершено от вашего имени.
person
Vlad Mihalcea
schedule
15.05.2014