簡體   English   中英

MapStruct:對象的映射列表,當對象從兩個對象映射時

[英]MapStruct: Map List of objects, when object is mapped from two objects

假設我有這樣的映射:

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

現在我需要將 ChildDto 列表映射到 Child 列表,但它們都具有相同的父級。 我希望做這樣的事情:

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

但它不起作用。 有機會做到嗎?

我按照 Gunnar 的建議使用了@AfterMapping

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

這確保所有問題都鏈接到同一個問卷實體。 這是避免 JPA 錯誤的解決方案的最后一部分, save the transient instance before flushing創建具有子項列表的新父實體save the transient instance before flushing

我找到了如何用裝飾器實現它,謝謝@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;
    }
}

我使用abstract class ,而不是映射器的interface ,因為在interface情況下,您無法排除生成方法map(List<Child> children, Parent parent) ,並且生成的代碼在編譯時無效。

就目前情況而言,這是不可能開箱即用的。 您可以使用裝飾器或后映射方法將父對象設置為之后的所有子對象。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM