首页 > 解决方案 > 通过 ModelMapper 映射抽象类

问题描述

我有这样一个简单的类结构,它有抽象类和子类。我希望它们使用ModelMapper映射到目标类结构。

我已经检查过,与映射抽象类相关的其他问题中的解决方案都没有解决我的问题。这条评论这条评论在某种程度上最接近我想要实现的目标,但在下面的场景中它仍然失败。

我得到的验证消息ModelMapper是:

org.modelmapper.MappingException: ModelMapper mapping errors:

1) Failed to instantiate instance of destination 
com.mls.services.MapperTest$DestParent. Ensure that 
com.mls.services.MapperTest$DestParent has a non-private no-argument 
constructor.
...

我很清楚 DestParent 类是抽象的,不能被实例化。

有什么办法可以使这个工作吗?

这是一个作为 JUnit 测试用例的测试源代码。如果我尝试解决此问题,底部的断言失败或验证会引发异常:

public class MapperTest {

  abstract static class SourceParent {}

  static class SourceSubA extends SourceParent {}

  static class SourceSubB extends SourceParent {}

  abstract static class DestParent {}

  static class DestSubA extends DestParent {}

  static class DestSubB extends DestParent {}

  static class Source {
    SourceParent item;

    public SourceParent getItem() {return item;}
    public void setItem(SourceParent item) {this.item = item;}
  }

  static class Dest {
    DestParent item;

    public DestParent getItem() {return item;}
    public void setItem(DestParent item) {this.item = item;}
  }

  @Test
  public void test() {
    ModelMapper modelMapper = new ModelMapper();

    TypeMap<Source, Dest> typeMap = modelMapper.createTypeMap(Source.class, Dest.class);

    // modelMapper.getConfiguration().setMatchingStrategy(MatchingStrategies.LOOSE);

    modelMapper
        .createTypeMap(SourceSubA.class, DestParent.class)
        .setConverter(
            mappingContext -> modelMapper.map(mappingContext.getSource(), DestSubA.class));

    modelMapper
        .createTypeMap(SourceSubB.class, DestParent.class)
        .setConverter(
            mappingContext -> modelMapper.map(mappingContext.getSource(), DestSubB.class));

    typeMap.addMapping(Source::getItem, Dest::setItem);

    TypeMap<SourceParent, DestParent> itemTypeMap =
        modelMapper.createTypeMap(SourceParent.class, DestParent.class);
    itemTypeMap.include(SourceSubA.class, DestSubA.class);
    itemTypeMap.include(SourceSubB.class, DestSubB.class);

    Source source = new Source();
    source.item = new SourceSubB();
    Dest dest = modelMapper.map(source, Dest.class);
    modelMapper.validate();

    Assert.assertTrue(dest.item instanceof DestSubB);
  }
}

标签: javamappingabstract-classconvertersmodelmapper

解决方案


推荐阅读