8

Assume I have such mapping:

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

Now I need to map List of ChildDto to List of Child, but they all have the same parent. I expect to do something like that:

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

But it doesn't working. Is there any chance to do it?

4

3 回答 3

5

我找到了如何用装饰器实现它,谢谢@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),并且生成的代码在编译时无效。

于 2016-06-13T18:04:15.260 回答
3

@AfterMapping按照 Gunnar 的建议使用了一个:

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

这确保了所有问题都链接到同一个问卷实体。save the transient instance before flushing这是避免在创建具有子列表的新父实体时出现JPA 错误的解决方案的最后一部分。

于 2018-06-15T07:12:28.850 回答
2

就目前情况而言,这不可能开箱即用。之后,您可以使用装饰器或后映射方法将父对象设置为所有子对象。

于 2016-05-31T06:37:05.683 回答