【问题标题】:JPA EntityManager blocks after @Transactional method@Transactional 方法之后的 JPA EntityManager 块
【发布时间】:2014-08-11 17:09:21
【问题描述】:

我有一个 Spring-JUnit 测试,其设置方法使用 JPA 实体来设置测试数据。在测试本身中,遗留代码使用 JDBC 模板来查询插入的测试数据。当遗留代码发出查询时,对 jdbcTemplate.query(...) 的调用会挂起。

我的单元测试如下所示:

@TransactionConfiguration(defaultRollback = false)
@ContextConfiguration(locations = { "/testContext.xml" })
@Transactional
public class MyTest {

    @PersistenceContext(unitName = "someUnit")
    private EntityManager entityManager;

    @Test
    public void test() {
        // here some legacy Code is called that uses JDBC Templates to query 
        // the inserted test data. The legacy code hangs upon jdbcTemplate.query(...)
    }

    @Before 
    public void before() {
        this.entityManager.persist(new Entity1(...));
        this.entityManager.persist(new Entity2(...));
    }

}

我的问题是:为什么 enitymanager 在退出 before() 方法时不提交?或者它是否提交并立即启动一个仍然引用存储实体的新事务?我还尝试不使用 junit 注释 @Before 注释并手动调用 before() 方法。但这给出了相同的结果。

非常感谢任何建议。

【问题讨论】:

    标签: java spring jpa junit transactions


    【解决方案1】:

    测试类

    @ContextConfiguration(locations = { "/testContext.xml" })
    @TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = false)
    @RunWith(SpringJUnit4ClassRunner.class)
    @Transactional
    public class MyTest extends AbstractTransactionalJUnit4SpringContextTests{
    
        @PersistenceContext(unitName = "someUnit")
        private EntityManager entityManager;
    
        @Autowired
        private BeforeService beforeService;
    
        @Test
        public void test() {
            beforeService.before();
            // here some legacy Code is called that uses JDBC Templates to query 
            // the inserted test data. The legacy code hangs upon jdbcTemplate.query(...)
        }
    
    }
    

    服务前

    public class BeforeService {
    
        private EntityManager entityManager;
    
        @PersistenceContext
        public void setEntityManager(final EntityManager entityManager) {
            this.entityManager = entityManager;
        }
    
        @Transactional(propagation=Propagation.REQUIRES_NEW)
        public void before() {
            entityManager.persist(new Entity1(...));
            entityManager.persist(new Entity2(...));
        }
    }
    

    我希望我已经为您提供了有关您问题的所有答案。

    【讨论】:

    • 谢谢。伟大的。事务注释仅在服务边界上处理。
    • 很高兴为您提供帮助:)
    猜你喜欢
    • 2018-04-12
    • 1970-01-01
    • 2016-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-08
    • 2018-03-21
    相关资源
    最近更新 更多