Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/378.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用ModelMapper映射抽象类型的字段_Java_Modelmapper - Fatal编程技术网

Java 使用ModelMapper映射抽象类型的字段

Java 使用ModelMapper映射抽象类型的字段,java,modelmapper,Java,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 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(新提供程序(){
@凌驾
公共基get(ProvisionRequestr){
返回新的A();
}
});
我还尝试像这样实现自定义转换器(也没有执行):

modelMapper.typeMap(A.class,Base.class).setConverter(newconverter()){
@凌驾
公共基转换(MappingContext MappingContext){
返回modelMapper.map(mappingContext.getSource(),A.class);
}
});
modelmapper似乎没有对字段使用这种类型映射,只对层次结构的根使用这种类型映射。
在这种情况下,如何映射类层次结构?

正如您所发现的,启用深度复制时会出现问题:
modelMapper.getConfiguration().setdeepcopydenabled(true)

解决方案是定义一个
转换器
,如下所示:

ModelMapper ModelMapper=newmodelmapper();
modelMapper.getConfiguration().setDeepCopyEnabled(true);//这就引发了问题
//转换器解决了这个问题
Converter BaseConverter=上下文->
modelMapper.map(context.getSource(),context.getSource().getClass());
createTypeMap(Base.class,Base.class).setConverter(baseConverter);


这是一篇关于这个主题的更详细的文章

正如您所发现的,启用深度复制时会出现问题:
modelMapper.getConfiguration().setDeepCopyEnabled(true)

解决方案是定义一个
转换器
,如下所示:

ModelMapper ModelMapper=newmodelmapper();
modelMapper.getConfiguration().setDeepCopyEnabled(true);//这就引发了问题
//转换器解决了这个问题
Converter BaseConverter=上下文->
modelMapper.map(context.getSource(),context.getSource().getClass());
createTypeMap(Base.class,Base.class).setConverter(baseConverter);


这是一篇关于这个主题的更详细的文章

您是否尝试在基类中添加非私有的无参数构造函数,如异常中所述?但基类是抽象的,当mm尝试使用反射实例化基类时,它实际上失败了。我想应该有一种方法可以明确地告诉modelmapper,Istate不是Base,而是DTO中接收到的同一个实现类,但是我找不到如何请提供一个,因为我无法解决目前发布的代码的问题。@MartinBG谢谢,我添加了一个主方法的示例,该方法在上面提供的异常情况下失败。请注意,为了简洁起见,省略了一些lombok注释。另外,我发现这个问题可以通过禁用deepcopy来解决(不幸的是,这并不总是可以接受)您是否尝试过像异常中所说的那样在基类中添加非私有的无参数构造函数?但是基类是抽象的,当mm试图使用反射实例化Base时,它实际上失败了。我想应该有一种方法可以明确地告诉modelmapper,Istate不是Base,而是DTO中接收到的同一个实现类,但是我找不到如何请提供一个,因为我无法解决目前发布的代码的问题。@MartinBG谢谢,我添加了一个主方法的示例,该方法在上面提供的异常情况下失败。请注意,为了简洁起见,省略了一些lombok注释。另外,我发现禁用deepcopy(不幸的是,这并不总是可以接受)可以解决这个问题。谢谢,这很有帮助。然而,我发现modelmapper还有一个非常棘手的问题:如果我在
modelmapper.createTypeMap(Base.class,Base.class)
之前使用
modelmapper.typeMap(DTO.class,Entity.class)
,它仍然会抛出异常。看起来,如果类DTO有类型为Base的字段,那么应该在DTO的类型映射之前定义Base的类型映射。谢谢,这很有帮助。然而,我发现modelmapper还有一个非常棘手的问题:如果我在
modelmapper.createTypeMap(Base.class,Base.class)
之前使用
modelmapper.typeMap(DTO.class,Entity.class)
,它仍然会抛出异常。似乎,若类DTO具有类型为Base的字段,则应在DTO的类型映射之前定义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);
            }
         });