首页 > 解决方案 > 使用 ModelMapper 映射抽象类型的字段

问题描述

我有以下类层次结构:

public abstract class Base {
    protected Boolean baseBoolean;
}
public class A extends Base {
    private BigDecimal amount;
}

并尝试将 DTO 映射到实体

public class DTO {
    private Base details;
}
public class Entity {
    private Base details;
}

并映射如下:

    public static void main(String[] args) {
        ModelMapper modelMapper = new ModelMapper();
        modelMapper.getConfiguration().setDeepCopyEnabled(true);

        A a = new A();
        a.setAmount(BigDecimal.ONE);
        a.setBaseBoolean(true);
        DTO request = DTO.builder().base(a).build();

        Entity entity = modelMapper.map(request, Entity.class);
        System.out.println(entity);
    }

我在详细信息字段中收到带有 A 或 B 的 DTO,这是使用调试器检查的。但是modelmapper抛出

无法实例化目标 org.package.Base 的实例。确保 org.package.Base 具有非私有的无参数构造函数。

我尝试使用显式提供程序(未用于此映射):

modelMapper.typeMap(A.class, Base.class).setProvider(new Provider<Base>() {
            @Override
            public Base get(ProvisionRequest<Base> r) {
                return new A();
            }
        });

我也尝试实现这样的自定义转换器(也没有执行):

modelMapper.typeMap(A.class, Base.class).setConverter(new Converter<A, Base>() {
            @Override
            public Base convert(MappingContext<A, Base> mappingContext) {
               return modelMapper.map(mappingContext.getSource(), A.class);
            }
         });

似乎模型映射器不将此类型映射用于字段,仅用于层次结构的根。在这种情况下如何映射类层次结构?

标签: javamodelmapper

解决方案


如您所见,启用深层复制时会出现问题:modelMapper.getConfiguration().setDeepCopyEnabled(true).

一个解决方案是定义Converter<Base, Base>如下:

ModelMapper modelMapper = new ModelMapper();
modelMapper.getConfiguration().setDeepCopyEnabled(true); // this triggers the problem

// the converter resolves it
Converter<Base, Base> baseBaseConverter = context ->
        modelMapper.map(context.getSource(), context.getSource().getClass());

modelMapper.createTypeMap(Base.class, Base.class).setConverter(baseBaseConverter);

现场演示

是有关该主题的更详细的帖子。


推荐阅读