问题描述:
两个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);
}
}
本文介绍了如何在单元测试中遇到的Spring JPA懒加载问题,即在使用OpenEntityManagerInViewFilter后,如何通过Spring上下文获取Session并确保事务管理来避免'couldnotinitializeproxy-noSession'异常。作者提供了具体代码示例,并分享了排错和解决方案。

828

被折叠的 条评论
为什么被折叠?



