我有一个简单的类结构,其中包含抽象类和子类。我希望使用ModelMapper将它们映射到目标类结构。
我已经检查过了,其他问题中与映射抽象类有关的解决方案都没有解决我的问题。 This comment和this comment在某种程度上与我想要达到的目标最接近,但是在下面的情况下它仍然失败。
我从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);
}
}