java - Hibernate 在 Spring 事务中抛出 TransactionRequiredException

标签 java spring hibernate jpa

Hibernate 在我的一个测试方法中抛出了 javax.persistence.TransactionRequiredException 。但是,根据日志,有一个事务正在进行中(由 Spring 创建)。有人知道我可能会错过什么吗?

查看日志:

INFO  org.springframework.test.context.transaction.TransactionalTestExecutionListener - Began transaction (1) for test context [DefaultTestContext@506dd108 testClass = FooTest, testInstance = com.example.FooTest@59b68d78, testMethod = test@FooTest, testException = [null], mergedContextConfiguration = [MergedContextConfiguration@6001ef4b testClass = FooTest, locations = '{classpath:/appContext.xml}', classes = '{}', contextInitializerClasses = '[]', activeProfiles = '{}', contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader', parent = [null]]]; transaction manager [org.springframework.jdbc.datasource.DataSourceTransactionManager@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 [DefaultTestContext@506dd108 testClass = FooTest, testInstance = com.example.FooTest@59b68d78, testMethod = test@FooTest, testException = javax.persistence.TransactionRequiredException: Executing an update/delete query, mergedContextConfiguration = [MergedContextConfiguration@6001ef4b 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)

最佳答案

我同意您应该使用 JpaTransactionManager。我还相信您需要将该方法标记为事务性的:

@Transactional
public void test() {

您可以通过在测试中硬编码事务开始和提交来调试它。它看起来像是指向 em.createQuery... 的异常(因此,如果您想进一步诊断,请对那里的事务进行硬编码)。

希望有一点帮助:)

关于java - Hibernate 在 Spring 事务中抛出 TransactionRequiredException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21960242/

相关文章:

javascript - jQuery改变Div的颜色

Java 嵌入到 HTML 中

Java根据文件名中的日期查找目录中的最新文件

java - JQuery AutoComplete 与 Spring MVC 返回列表,但未过滤

java - 无法使用hibernate将数据库保存到h2数据库

java - 使用 JSON 中的值填充数组很棘手

java - 结合 2 个间隔

java - 如何使用 Spring Security 的新 PasswordEncoder

java - org.hibernate.HibernateException [org.postgresql.util.PSQLException : Large Objects may not be used in auto-commit mode.]

java - 从泛型类派生的类没有获得正确的类型