Hibernate在我的一個測試方法中拋出了javax.persistence.TransactionRequiredException
。但是,根據日誌,正在進行的交易(由Spring創建)。有沒有人知道我可能會錯過什麼?Hibernate在Spring事務中拋出TransactionRequiredException
查看日誌:
INFO org.springframework.test.context.transaction.TransactionalTestExecutionListener - Began transaction (1) for test context [[email protected] testClass = FooTest, testInstance = [email protected], testMethod = [email protected], testException = [null], mergedContextConfiguration = [[email protected] testClass = FooTest, locations = '{classpath:/appContext.xml}', classes = '{}', contextInitializerClasses = '[]', activeProfiles = '{}', contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader', parent = [null]]]; transaction manager [o[email protected]1f05562b]; rollback [true]
INFO com.example.FooTest - Test started.
INFO org.springframework.test.context.transaction.TransactionalTestExecutionListener - Rolled back transaction after test execution for test context [[email protected] testClass = FooTest, testInstance = [email protected], testMethod = [email protected], testException = javax.persistence.TransactionRequiredException: Executing an update/delete query, mergedContextConfiguration = [[email protected] testClass = FooTest, locations = '{classpath:/appContext.xml}', classes = '{}', contextInitializerClasses = '[]', activeProfiles = '{}', contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader', parent = [null]]]
我的測試類是:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/appContext.xml")
@Transactional
public class FooTest {
private static final Logger logger = LoggerFactory.getLogger(FooTest.class);
@PersistenceContext
private EntityManager em;
@Test
public void test() {
logger.info("Test started.");
em.createQuery("delete from Foo").executeUpdate();
logger.info("Test finished.");
}
}
我appContext.xml是:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/jdbc
http://www.springframework.org/schema/jdbc/spring-jdbc.xsd">
<bean id="embeddedEmf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="embeddedDataSource"/>
<property name="persistenceUnitName" value="Foo" />
</bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="embeddedDataSource"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
<jdbc:embedded-database id="embeddedDataSource">
<jdbc:script location="classpath:schema.sql" encoding="UTF-8"/>
<jdbc:script location="classpath:test-data.sql" encoding="UTF-8"/>
</jdbc:embedded-database>
</beans>
我的META-INF/persistence.xml中是相當直截了當:
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">
<persistence-unit name="Foo">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<class>com.example.Foo</class>
</persistence-unit>
</persistence>
最後,堆棧跟蹤(過濾):
javax.persistence.TransactionRequiredException: Executing an update/delete query
at org.hibernate.jpa.spi.AbstractQueryImpl.executeUpdate(AbstractQueryImpl.java:71)
at com.example.FooTest.test(FooTest.java:27)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:232)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:89)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:175)
使用屬於您的技術的事務管理器。您正在使用JPA,因此請使用'JpaTransactionManager'而不是'DataSourceTransactionManager'。 –
非常感謝。就是這樣。 –
@ M.Deinum我在應用程序中同時使用了SpringJDBC和JPA。使用JPATransactionManager會在我使用SpringJDBC的地方給出錯誤,並且在我使用JPA的地方使用DataSourceTransactionManager給出錯誤。任何方式呢? – Dojo