У меня такая простая структура классов, в которой есть абстрактные классы и подклассы.Я хочу, чтобы они были сопоставлены со структурой класса назначения с помощью 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);
}
}