【问题标题】:@Transactional in unit test prevents @PostLoad from being invoked单元测试中的@Transactional 阻止调用@PostLoad
【发布时间】:2012-08-13 13:11:55
【问题描述】:

我有以下测试:

public class Book
{
     public boolean postLoadInvoked;
     @PostLoad
     private void onPostLoad()
     {
         postLoadInvoked = true;
     }
}

public class MyIntegrationTest extends AbstractIntegrationTest
{
     @Autowired
     private BookDAO bookDAO;

     @Test
     public void loadBooks()
     {
          Book book = bookDAO.findOne(...);
          assertTrue(book.postLoadInvoked);
     }  
}

此测试按原样通过,但如果我将 @Transactional 注释添加到测试类,它会失败:

@Transactional
@TransactionConfiguration(defaultRollback=true)
public class MyIntegrationTest extends AbstractIntegrationTest

为什么用@Transactional 配置测试会影响JPA 回调方法?

编辑

DAO 只是一个 Spring Data 存储库,因此没有逻辑:

public interface BookDAO extends
   JpaRepository<Book, Long>, 
   QueryDslPredicateExecutor<Book> {}

事务管理器也有标准配置:

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory" />
    <property name="dataSource" ref="dataSource" />
</bean>

<bean id="entityManagerFactory"
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="packagesToScan">
        <list>
            <value>com.mangofactory.example</value>
        </list>
    </property>
    <property name="persistenceUnitName" value="spring-test" />
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
            <property name="showSql" value="true" />
            <property name="generateDdl" value="true" />
            <property name="databasePlatform" value="org.hibernate.dialect.H2Dialect" />
        </bean>
    </property>
</bean>

<bean id="dataSource"
    class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="org.h2.Driver" />
    <property name="url" value="jdbc:h2:mem:test;DB_CLOSE_DELAY=-1" />
</bean>

【问题讨论】:

  • 可以添加bookDao代码和transactionManager的配置吗?
  • @gkamal 当然,更新了更多配置。
  • 您的@PostLoad 方法无法编译...它没有返回类型。您确定在编译此更改后运行测试吗?
  • @jordan002 很好 - 谢谢。但这只是这篇文章中的一个错字。是的,测试肯定会运行。我在我的项目中的大约十几个集成测试中遇到了同样的问题。

标签: java spring hibernate unit-testing jpa


【解决方案1】:

我不确定您使用的是什么 spring 版本,或者 AbstractIntegrationTest 是否正在扩展某些东西,但要检查的一件事是,在您的层次结构中,您的测试应该扩展一些抽象的事务上下文感知 spring 测试类。

我正在考虑的课程:

org.springframework.test.AbstractTransactionalSpringContextTests
org.springframework.test.AbstractTransactionalDataSourceSpringContextTests

或一些 jUnit 风格(取决于您使用的版本):

org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests
org.springframework.test.context.junit38.AbstractTransactionalJUnit38SpringContextTests

【讨论】:

    【解决方案2】:

    我可以想到两个原因:

    1. @PostLoad 仅在事务提交后执行。不太可能。

    2. 您是如何启用事务的?你指定proxyTargetClass = true了吗?否则,您可能会遇到奇怪的行为。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-09-30
      • 1970-01-01
      • 1970-01-01
      • 2020-10-26
      • 1970-01-01
      • 2016-07-17
      • 2016-04-17
      相关资源
      最近更新 更多