Предпосылка
У меня есть проект Spring 5.1.5 с Hibernate 5.4.1
Компиляция проходит нормально, но при выполнении тестовых случаев для конкретного пакета Iувидеть, что несколько тестов провалились.Все с одинаковой ошибкой:
javax.persistence.TransactionRequiredException: транзакция не выполняется в com.project.server.package.dao.impl.SomeDAOImplTest.someTest (SomeDAOImplTest.java:54)
Проблема
Теперь я знаю, что Hibernate 5 принудительно проверяет транзакцию, но не находит ее здесь и выдает исключение.У меня вопрос, почему это происходит, если у меня есть транзакции, инициализированные через контекст Spring.
Мой тестовый пример:
@ContextConfiguration({ "classpath:/spring/applicationContext-package-dao--test.xml" })
public class SomeDAOImplTest extends AbstractDAOTest {
@Autowired
private SomeDAO someDAO;
private className obj;
@Before
public void setUp() {
obj = new ClassName();
obj.setId(3);
someDAO.saveOrUpdate(obj);
}
Мой applicationContext-package-dao--test.xml
:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<import resource="classpath:/spring/applicationContext-persistence-datasource-test.xml" />
<import resource="classpath:/spring/applicationContext-package-dao.xml" />
</beans>
Импортированный контекст applicationContext-persistence-datasource-test.xml
имеет компонент txProxyTemplate
, как показано ниже:
<beans>
.
.//other beans
.
<bean id="txProxyTemplate" abstract="true" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager" ref="transactionManager" />
</bean>
<bean id="transactionManager" class="com.desktone.transaction.DtResourcelessTransactionManager" />
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />
.
.//other beans
.
</beans>
Другой applicationContext-package-dao.xml
имеет определение компонента для SomeDAO
, родительским элементом которого является txProxyTemplate
.
<bean id="SomeDAO" parent="txProxyTemplate">
<property name="target">
<bean class="com.project.server.package.dao.impl.SomeDAOImpl">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
</property>
<property name="transactionAttributes">
<props>
<prop key="saveOrUpdate">PROPAGATION_REQUIRED</prop>
<prop key="delete">PROPAGATION_REQUIRED</prop>
<prop key="*">PROPAGATION_SUPPORTS,readOnly</prop>
</props>
</property>
</bean>
вызов saveorupdate от SomeDAOImplTest
вызывает SomeDAOImpl
, чей контекстный контекст весны равен applicationContext-package-dao.xml
и имеет вызов Hibernate saveorupdate()
.
Вещи, которые я пробовал:
- Добавление тега @Transactional вручную в SomeDAOImplTest.(по-прежнему не выдает ошибку tx)
- Экспериментирует с PROPAGATION.REQUIRES_NEW (по-прежнему не выдает ошибку tx) & PROPAGATION.MANDATORY (говорит, что помечено как обязательное, но не передает).
- Удостоверился, что автопровод инициализируетсябин.
Первичное подозрение
Я подозреваю, что бин someDAO
каким-то образом инициализирован, а бин txProxyTemplate
- нет, поэтому нет transactionManager
на месте.Однако я не нашел никаких подсказок, подтверждающих это.