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

MapStruct:从两个对象映射对象时,对象的映射列表

沈子实
2023-03-14

假设我有这样的映射:

@Mapping(source = "parentId", target = "parent.id")
Child map(ChildDto dto, Parent parent);

现在,我需要将子列表映射到子列表,但它们都有相同的父对象。我希望这样做:

List<Child> map(List<ChildDto> dtoList, Parent parent);

但不管用,有机会做吗?

共有3个答案

唐修诚
2023-03-14

从目前的情况来看,这是不可能的。可以使用decorator或after-mapping方法将父对象设置为之后的所有子对象。

笪智志
2023-03-14

我使用了Gunnar建议的@AfterMapping

@AfterMapping
public void afterDtoToEntity(final QuestionnaireDTO dto, @MappingTarget final Questionnaire entity) {
  entity.getQuestions().stream().forEach(question -> question.setQuestionnaire(entity));
}

这确保了所有问题都链接到同一个问卷实体。这是避免JPA错误的解决方案的最后一部分。在创建一个包含子实体列表的新父实体时,在刷新之前保存临时实例

曹高阳
2023-03-14

我找到了如何用decorators实现它,谢谢@Gunnar这里是一个实现:

public class Child {
    int id;
    String name;
}
public class Parent {
    int id;
    String name;
}
public class ChildDto {
    int id;
    String name;
    int parentId;
    String parentName;
}
// getters/settes ommited
@Mapper
@DecoratedWith(ChildMapperDecorator.class)
public abstract class ChildMapper {
    public static final ChildMapper INSTANCE = Mappers.getMapper(ChildMapper.class);

    @Mappings({
            @Mapping(target = "parentId", ignore = true),
            @Mapping(target = "parentName", ignore = true)
    })
    @Named("toDto")
    abstract ChildDto map(Child child);

    @Mappings({
            @Mapping(target = "id", ignore = true),
            @Mapping(target = "name", ignore = true),
            @Mapping(target = "parentId", source = "id"),
            @Mapping(target = "parentName", source = "name")
    })
    abstract ChildDto map(@MappingTarget ChildDto dto, Parent parent);

    @IterableMapping(qualifiedByName = "toDto") // won't work without it
    abstract List<ChildDto> map(List<Child> children);

    List<ChildDto> map(List<Child> children, Parent parent) {
        throw new UnsupportedOperationException("Not implemented");
    }
}
public abstract class ChildMapperDecorator extends ChildMapper {
    private final ChildMapper delegate;

    protected ChildMapperDecorator(ChildMapper delegate) {
        this.delegate = delegate;
    }

    @Override
    public List<ChildDto> map(List<Child> children, Parent parent) {
        List<ChildDto> dtoList = delegate.map(children);
        for (ChildDto childDto : dtoList) {
            delegate.map(childDto, parent);
        }
        return dtoList;
    }
}

我使用抽象类,而不是接口作为映射器,因为在接口的情况下,您无法排除生成方法map(列表

 类似资料:
  • 下面是我的DTO。 源DTO 目标DTO

  • 给定: 我想把所有的车都标出来。将轮胎分为单独的轮胎板。我知道我可以做一个

  • 我试图使用MapStruct在dto和实体对象之间映射convert,但是生成的映射器实现只返回空的映射对象。 BeermapperImpl 任何人都可以提供我的代码可能出错的地方?谢谢!

  • 我有Object1和Object2。现在,我想映射对象3,属性来自1 比方说,我有两个目标: 现在,有了这些,我想把它映射进去 哪里,first_name 现在,我的问题是,怎么做? 然而,目前,我正在这样做 但是,在这里,我必须在addressToView()中手动编写映射。 因此,有没有办法避免这种情况? 或者,处理此类情况的首选方式是什么?

  • 我创建映射如下所示。如何将平面dto对象属性(街道、城市等)映射到域对象中的嵌套地址。当我试着去做的时候,我发现了一个错误: [错误]诊断:返回类型中的属性“Address.PostalCode”未知。@Mapping(来源=“City”,目标=“Address.City”), 还有类...