在spring boot集成测试中获取org.hibernate.LazyInitializationException

Posted

技术标签:

【中文标题】在spring boot集成测试中获取org.hibernate.LazyInitializationException【英文标题】:Get org.hibernate.LazyInitializationException in spring boot integration test 【发布时间】:2016-07-03 23:18:41 【问题描述】:

我正在尝试为 Spring Boot 应用程序编写集成测试。我有 Product 和 GalleryImage 域模型。它们是一对多的关系。

public class Product 
    ...

    @OneToMany(mappedBy = "product")
    private List<GalleryImage> galleryImages;

我有一个集成测试如下:

@Test
public void testProductAndGalleryImageRelationShip() throws Exception 
    Product product = productRepository.findOne(1L);
    List<GalleryImage> galleryImages = product.getGalleryImages();
    assertEquals(1, galleryImages.size());

但是,这个测试给了我一个 LazyInitializationException。我在 Google 和 *** 上搜索,它说 session 在 productRepository.findOne(1L) 之后关闭,因为galleryImages 是延迟加载的,所以galleryImages.size() 给了我这个异常。

我尝试在测试中添加@Transactional注解,但还是不行。

【问题讨论】:

您可能需要在测试顶部添加@Transactional 来修复它。但我可能会将您的代码移至服务并为服务方法添加注释。 我尝试在测试中添加@Transactional,但没有成功。我是否需要添加一些配置来启用@Transactional? 你的测试有SpringJUnit4ClassRunner吗? 【参考方案1】:

Hibernate Session 在productRepository.findOne(1L) 之后已经关闭。

你可以试试Hibernate.initialize(product.getGalleryImages())

public static void initialize(Object proxy)
                   throws HibernateException

强制初始化代理或持久集合。 注意:这只确保代理对象或集合的初始化;不保证集合内的元素将被初始化/实现。

要避免Hibernate.initialize,您可以创建一个服务。

@Service
@Transactional
public class ProductService 

    @Transactional(readOnly = true)
    public List<GalleryImage> getImages(final long producId) throws Exception 
      Product product = productRepository.findOne(producId);
      return product.getGalleryImages();
  

如果您确实在应用程序中使用Spring Data JPA,那么动态查找器是一个不错的选择。

【讨论】:

以上是关于在spring boot集成测试中获取org.hibernate.LazyInitializationException的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot集成测试无法在命令行未指定配置文件时获取默认配置文件并抛出错误

Spring Boot入门——集成Mybatis

使用 Spring Boot 在单元测试中配置集成测试或使用 Spring JDBC?

Spring Boot 集成测试:模拟环境接口

@WithMockUser 在集成测试中不起作用 - Spring boot

使用放心的spring-boot集成测试