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

递归映射时的MapSTRt问题

狄飞鹏
2023-03-14

我正在尝试实现MapStruct映射库。我制作了一些示例,对于简单的映射,它工作得很好,但我在1期中遇到了问题。我有2个jpa实体类,它们具有双向关系。一个在另一个里,另一个在一个里。它会产生循环映射问题,因此MapStruct会引发StackOverflow错误。我已经创建了最少的代码来在github上重现这个案例。示例代码:

public class A {
    private Long id;
    private String name;
    private B bData;
    //getter-setter
}

public class B {
    private Long id;
    private String name;
    private Set<A> aData;
    //getter-setter
}

数据生成器

public class DataGenerator {
    public static A generateData(){
        A a = new A();
        a.setId(1L);
        a.setName("foo");
        B b = new B();
        b.setId(2L);
        b.setName("bar");

        A a2 = new A();
        a2.setId(3L);
        a2.setName("john");
        a2.setbData(b);
        A a3 = new A();
        a3.setId(4L);
        a3.setName("doe");
        a3.setbData(b);

        Set<A> aData = new HashSet<A>();
        aData.add(a2);
        aData.add(a3);
        b.setaData(aData);

        a.setbData(b);
        return a;
    }
}

映射器

@Mapper
public interface CustomMapper {
    CustomMapper INSTANCE = Mappers.getMapper(CustomMapper.class);
    ADto atoADto(A a);
}

应用程序

public class AppMain {
    public static void main(String[] args) {
        A a = DataGenerator.generateData();
        ADto aDto = CustomMapper.INSTANCE.atoADto(a);
        System.out.println(aDto.getId());
    }
}

Dto/目标类与原始源类相同。主要是循环/递归映射问题,这会导致stackoverflow错误。

同样的事情使用Spring BeanUtils.copy属性,但我想实现MapSTRt。目前我正在考虑用MapSTRt替换Spring BeanUtils。

有什么建议吗?

共有2个答案

哈朗
2023-03-14

MapSTRt存储库中有一个如何处理循环和递归的示例。基本上您需要跟踪状态。该示例使用上下文对象来做到这一点。

阎英朗
2023-03-14

请参阅此mapstruct github问题以了解解决方案,即忽略导致递归的字段。我引用:

“您可以使用@限定符来实现它。您可以使用@Named和qualifiedByName,也可以使用您自己的自定义@CountryWithoutCities限定符和qualifiedBy。

Class country{

     String id;
     String name;
     List<City> cities;
}

Class City{

     String id;
     String name;
     Country country;
}

@Mapper(uses = CityMapper.class)
interface CountryMapper {

    @Mapping( target = "cities", qualifiedByName = "noCountry")
    CountryDto toDto(Country country);

    @CountryWithoutCities
    @Mapping( target = "cities", ignore = true)
    CountryDto toDtoWithoutCities(Country country);
}

@Mapper(uses = CountryMapper.class)
interface CityMapper {

    @Named( "noCountry" )
    @Mapping( target = "country", ignore = true)
    CityDto toDtoWithoutCountry(City city);

    @Mapping( target = "country", qualifiedBy= CountryWithoutCities.class)
    CityDto toDto(City city);
}
 类似资料:
  • 我正在努力将非平凡函数映射为尾递归。 就拿简单的玫瑰树来说 带地图 (更不用说绑定了) 使这种尾部递归似乎很痛苦,我已经看过了FSharpx之类的例子,但它们不是尾部递归的。我找到了这个 https://www.gresearch.co.uk/article/advanced-recursion-techniques-in-f/ 但是,从基于连续性的最后一个示例开始的飞跃似乎相当符合他们的示例(m

  • 我使用静态编程语言反射来检查具有特定注释的属性是否为空。 给出以下示例: 以及检查它的函数: 这个想法是,函数将迭代我的类的属性,检查它们是否有注释,并检查值是否为空。如果属性是一个数据类,代码会递归地计算Childs的属性。 之后,我映射结果,将KProperty转换为一个简单的字符串,该字符串可供人阅读,包含类名和属性名。 问题是上面的代码没有按预期工作。返回的属性只是来自第一级类的属性。 如

  • 问题内容: 我试图递归地反映一个结构,打印出每个字段的类型。在字段是结构片段的情况下,我希望能够识别数组中保存的类型,然后在该类型上进行反映。 这是一些示例代码 输出看起来像这样: 当我确定字段类型是指针的一部分时,我可以通过调用subtype.Elem()来推断类型。 输出为“ main.child” 如果我然后尝试反映孩子使用 我得到以下内容: 如何使用反射API遍历子结构的字段? 问题答案:

  • 我有一个任意嵌套的迭代程序,如下所示: 我想在不改变结构的情况下映射一个函数。例如,我可能希望将所有数字转换为字符串,以获取 有什么好办法吗?我可以编写自己的方法来手动遍历,但我想知道是否有一种通用的方法来映射递归迭代表。

  • 问题内容: 给定一个,其中值是a 或另一个,那么如何使用Java 8将地图展平到单个值列表? 例: 对于上面的示例,我想要以下列表: 我知道可以这样做: 我该如何使用? 编辑: 经过一番游戏后,我发现了: 问题答案: 您可以定义一个递归方法来展平一个地图并将其用作函数或直接调用它来使用。 例: 对于给定的嵌套地图,它会打印 [value1,value2,value3.1,value3.2,valu

  • 我在使用模型映射器使用执行父子实体更新时遇到了一个问题。 描述如下 父类: 儿童班: 通过这种安排,我能够成功地创建和查询站点地址组合。但是,我在进行更新时遇到了一个问题。我正在尝试使用modelmapper语句更新站点或地址,如下所示: 期望在传入站点中更改的所有字段(即来自请求的站点)应替换站点中的现有字段。但是,我从modelmapper中得到一个Stackoverflow错误。 我们是否有