当前位置: 首页 > 知识库问答 >
问题:

Spring modelmapper映射延迟加载的实体

爱炯
2023-03-14

我正在使用模型映射器(http://modelmapper.org/)将具有延迟加载对象列表(通过Hibernate)的实体映射到具有modelmapper.map()的DTO。

输出dto的列表为空值,但实体的列表已填充。当我改为“急切加载”时,一切正常,但我的查询太大,所以这不是一个选项。

有人知道模型映射器如何映射代理的Hibernate实体类吗?

这是我的父实体:

public class Category {

    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "category")
    @OrderBy("sortOrder")
    private SortedSet<CategorySubarea> categorySubareas;
}

运输署署长:

@Data
@AllArgsConstructor
@NoArgsConstructor
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS)
public class CategoryDto {

    private LinkedHashSet<@Valid CategorySubareaDto> categorySubareas;
}

这是我如何使用映射器(源类别是实体,目的地类别是dto):

modelMapper.map(sourceCategory, destinationCategory);

当然,这样的方法是可行的,但这是一个非常丑陋的解决方法:

            sourceCategory.getCategorySubareas().forEach(subarea -> {
               // do nothing here
            });
            modelMapper.map(sourceCategory, destinationCategory);

共有1个答案

章博耘
2023-03-14

我知道用mapstruct处理lazy/dto的好方法。只需创建自定义上下文类

public class CycleAvoidingMappingContext {

  private Map<Object, Object> knownInstances = new IdentityHashMap<Object, Object>();
  PersistenceUtil persistenceUnitUtil = Persistence.getPersistenceUtil();

  @SneakyThrows
  @BeforeMapping
  public <T> T getMappedInstance(Object source, @TargetType Class<T> targetType) {
    if (source != null) {
      for (PropertyDescriptor pd : Introspector.getBeanInfo(source.getClass()).getPropertyDescriptors()) {
        if (pd.getWriteMethod() != null && pd.getReadMethod() != null && !"class".equals(pd.getName())) {
          var vvalue = pd.getReadMethod().invoke(source);

          if (vvalue == null) {
            continue;
          }

          var classs = vvalue.getClass();
          if (HibernateProxy.class.isAssignableFrom(classs)) {
            try {
              if (Hibernate.isInitialized(vvalue) == false) {
                pd.getWriteMethod().invoke(source, null);
              }
            } catch (Exception e) {
            }
          }
        }
      }
    }
    return (T) knownInstances.get(source);
  }

  @BeforeMapping
  public void storeMappedInstance(Object source, @MappingTarget Object target) {
    knownInstances.put(source, target);
  }
}

然后像这样使用它:

CrmClientMapper.INSTANCE.getDto(client, new CycleAvoidingMappingContext());

它将跳过惰性字段,因此您不会获得惰性初始化异常和对数据库的不必要查询。只是实体图,用于指定要获取的关系。

 类似资料:
  • 描述 (Description) 延迟加载可应用于图像,背景图像和淡入效果,如下所述 - 对于图像 要在图像上使用延迟加载,请按照给定的步骤进行操作 - 使用data-src属性而不是src属性来指定图像源。 将类lazy添加到图像。 <div class = "page-content"> ... <img data-src = "image_path.jpg" class = "l

  • 我们的网站通过Netscaler运行,我们已经激活了图像的延迟加载。我试图了解它的功能,以及它是否可以以任何方式控制。例如,如果可以将特定图像设置为非延迟加载。但是我找不到关于它的具体实现的任何东西,只找到描述如何激活它的文章。 如果我理解正确,它就像经典的基于js的lazyloading一样,通过添加类lazy并将src移动到数据原始属性来转换imagetags。然后,当滚动到视图中时,java

  • 问题内容: 如果这是完全相同的内容,请纠正我,我知道这个话题经常被讨论,但是找不到确切的答案。 问题: 在MVC Web应用程序中处理Hibernate对象的最佳实用解决方案是什么? 细节: 我正在使用Hibernate,并希望在可能的情况下利用延迟加载。 我正在使用MVC风格的Webapp。 我讨厌获得延迟加载初始化异常。 我讨厌不得不在事务之间重新连接Hibernate对象。 选项: 渴望装载

  • 本文向大家介绍Webpack 实现 AngularJS 的延迟加载,包括了Webpack 实现 AngularJS 的延迟加载的使用技巧和注意事项,需要的朋友参考一下 随着你的单页应用扩大,其下载时间也越来越长。这对提高用户体验不会有好处(提示:但用户体验正是我们开发单页应用的原因)。更多的代码意味着更大的文件,直到代码压缩已经不能满足你的需求,你唯一能为你的用户做的就是不要再让他一次性下载整个应

  • 问题内容: 我在JPA实体中的延迟加载属性有问题。我读过许多类似的问题,但它们与spring或hibernate有关,并且他们的后代不适用或没有帮助。 该应用程序是在Wildfly应用程序服务器上运行的JEE和JPA2.1。有两个实体,DAO会话bean和servlet将它们放在一起: 当我运行此代码时,它失败并显示: 我对WebLogic / JPA1使用了非常相似的模式,并且运行平稳。任何的想

  • 问题内容: 我想知道在node.js中使用是否等效于延迟加载? 例如,如果我有一个函数需要代码中其他任何地方都不需要的特定node.js包,那么我最好在该函数内部使用它,以便仅在调用该函数时才包含所需的包。 我还不确定是否会由于缺乏对node.js架构的了解而在性能方面有所改善?我想它每次与服务器的连接都会使用更少的内存。但是,当它必须读取程序包时,它会增加磁盘的I / O吗,还是将其添加到内存中