【问题标题】:Exception: org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role异常:org.hibernate.LazyInitializationException:未能延迟初始化角色集合
【发布时间】:2019-12-31 08:42:08
【问题描述】:

我正在开发一个 Spring Boot 应用程序。我开发了一种功能,可以很好地运行而不会出错。但是,当我使用相同的代码进行集成测试时,出现以下错误:

partnerOrderHeaders assoc2s

org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: package.Object1.assoc2s, could not initialize proxy - no Session

这是出现错误的方法

private  List<ObjectClusterData> constructObjectClusterDataFromObject1(Object1 Object1) {
    List<ObjectClusterData> ObjectClusterDatas = new ArrayList<ObjectClusterData>();
    ObjectClusterData ObjectClusterData = new ObjectClusterData();
    Set<Assoc1> Assoc1s = Object1.getPartnerOrderHeaders();
    Object2 Object2 = null;
    Set<Object2> Object2s = null;
    ObjectItemClusterData ObjectItemClusterData = null;
    for (Assoc1 Assoc1 : Assoc1s) {
        ObjectClusterData = new ObjectClusterData();
        Object2 = Assoc1.getHeader();
        ObjectClusterData.setNum(Object2.getNum());
        PartData partData = Object1 != null ? ConvertDomainObjectToDataObjectAndReverse.convertObject1ToPartData(Object1) : null;
        ObjectClusterData.setPartDatas(Arrays.asList(new PartData[]{partData}));
        Object2s = Object2.getItems();
        List<ObjectItemClusterData> ObjectItemClusterDatas = new ArrayList<ObjectItemClusterData>();
        for (Object2 Object2 : Object2s) {
            ObjectItemClusterData = new ObjectItemClusterData();
            ObjectItemClusterData.setProperty1(Object2.getProperty1());
            ObjectItemClusterData.setProperty2(Object2.getProperty2());
            ObjectItemClusterData.setProperty3(Object2.getProperty3());
            ObjectItemClusterData.setDimData(Object2.getDim() != null ? ConvertDomainObjectToDataObjectAndReverse.convertDimObjectToDimObjectData(Object2.getDim()) : null);
            ObjectItemClusterData.setMat(Object2.getMaterials() != null ? ConvertDomainObjectToDataObjectAndReverse.convertDimMatObjectToMatObjecData(Object2.getMat()) : null);
            ObjectItemClusterDatas.add(ObjectItemClusterData);
        }
        ObjectClusterData.setObject2s(ObjectItemClusterDatas);
        ObjectClusterDatas.add(ObjectClusterData);
    }
    return ObjectClusterDatas;

}

错误发生在这一行

   for (Assoc1 Assoc1 : Assoc1s){

但重要的是,该功能可以正常工作,而它在集成测试部分不起作用。我认为我错过了测试部分中设置的配置。你能帮帮我吗

按照尼克的要求,我添加了测试代码

    @Test
    @WithMockUser(username = LOGIN, password = PASSWRD, roles = ROLE)
    public void testGetOrderReferenceByOrderWithNoError() throws Exception {

        // getInsertAndUpdateModificationInDateWindow
          restCustomerOrderMockMvc
      .perform(get("/api/orders/modification?"
              +"beginInsertionOrModificationDate=" + ORDER_ZONE_DATE_TIME_NO_1+
              "&endInsertionOrModificationDate=" + ORDER_ZONE_DATE_TIME_NO_4)
      .accept(MediaType.APPLICATION_JSON))
      .andExpect(status().isOk()).andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE))
      .andExpect(jsonPath("$.resultCode").value(BusinessErrorCode.NO_ERROR.getCode()))
      .andExpect(jsonPath("$.size").value("1"))
      .andExpect(jsonPath("$.entities[0]." + F_OBJECT1_NUM).value(NUM_1))                
      .andExpect(jsonPath("$.entities[0].partDatas[0]" + F_USER_COM_API).value(PART_1))
      .andExpect(jsonPath("$.entities[0].Object2s[0]" + F_ITEM_NO).value(ITEM_NO_1))
      .andExpect(jsonPath("$.entities[0].Object2s[0].dimensionData." + F_WEIGHT.value(WEIGHT))
      .andExpect(jsonPath("$.entities[0].Object2s[0].materialData." + F_GRADE).value(GRADE_1));  
}

【问题讨论】:

  • 请添加测试代码
  • 嗨尼克,我添加了测试代码

标签: spring spring-boot integration-testing lazy-initialization


【解决方案1】:

您应该在 OneToMany 关系 DimPartner 和 FactAssocPartnerOrderHeader 中设置 FetchType.EAGER

【讨论】:

  • 嗨尼克,我已经考虑过了,但是为了应用程序的需要,我必须在运行该功能时保持 LAZY 加载。正如我提到的,错误只发生在测试部分。应该有另一个修复,因为当我从浏览器中点击 API 并且考虑到延迟加载时它可以完美运行。与测试部分有什么区别?我认为有一个解决方法
  • 好的。尝试添加字符串 Hibernate.initialize(dimPartner.getPartnerOrderHeaders());
  • 嗨尼克,结果是一样的。在添加的行中提到了相同的错误,即 Hibernate.initialize(dimPartner.getPartnerOrderHeaders());
  • 我在集成测试中补充说,我有一个内存数据库
【解决方案2】:

我终于找到了解决方案:在测试类上添加@Transactional注解。感谢您的回复

【讨论】:

  • 理想情况下,您不应该在测试类上添加事务。你的代码应该管理事务而不是测试类。
猜你喜欢
  • 2015-05-03
  • 2013-12-08
  • 2017-08-04
  • 1970-01-01
  • 1970-01-01
  • 2019-03-13
  • 1970-01-01
  • 2019-08-06
  • 2017-08-16
相关资源
最近更新 更多