问题描述:
两个model:salesOrder SalesOrderItem 为oneToMany fetch = FetchType.LAZY
单元测试从数据库获取salesOrder后,获取其子集合List<SalesOrderItem> salesOrderItems
报如下异常
分析原因之后发现过滤器中引入了OpenEntityManagerInViewFilter来将一个JPAsession与一次完整的请求过程对应的线程相绑定,但是该过滤器只对controller层的请求起作用,对于mq或者定时任务的对象获取就会报could not initialize proxy - no Session,OpenEntityManagerInViewFilter将JPAsession统一交由spring管理,所以从spring上下文中获取session,操作完之后再关闭,就可解决问题代码如下:
package com.wintelia.orderserver.api.controller.order; import com.foreveross.callcenter.domain.sale.SalesOrder; import com.foreveross.callcenter.domain.sale.SalesOrderItem; import com.wintelia.orderserver.api.OderServerApiApplication; import com.wintelia.orderserver.application.service.order.SalesOrderService; import org.junit.Test; import org.junit.runner.RunWith; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.context.ApplicationContext; import org.springframework.orm.jpa.EntityManagerFactoryUtils; import org.springframework.orm.jpa.EntityManagerHolder; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.transaction.support.TransactionSynchronizationManager; import javax.annotation.Resource; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; @RunWith(SpringRunner.class) @SpringBootTest(classes = OderServerApiApplication.class) public class OrderDetailLazyTest { @Autowired private SalesOrderService orderService; private static final Logger log = LoggerFactory.getLogger(OrderDetailLazyTest.class); @Resource private ApplicationContext ctx; @Test public void queryOrderBySysOrderNo() { EntityManagerFactory entityManagerFactory = ctx.getBean(EntityManagerFactory.class); EntityManager entityManager = entityManagerFactory.createEntityManager(); EntityManagerHolder entityManagerHolder = new EntityManagerHolder(entityManager); TransactionSynchronizationManager.bindResource(entityManagerFactory, entityManagerHolder); SalesOrder salesOrder = orderService.findByOrderNo2("*******"); for(SalesOrderItem item : salesOrder.getSalesOrderItems()){ log.info("票号信息为{}",item.getTicketNo()); } TransactionSynchronizationManager.unbindResource(entityManagerFactory); EntityManagerFactoryUtils.closeEntityManager(entityManager); } }