问题
I am using ModelMapper Framework (http://modelmapper.org/) for mapping objects in Java. I have encountered a problem while mapping concrete classes (DTO to Entites) containing abstract classes.
Example:
Task has a list of AbstractItems.
AbstractItems are Question and Criteria.
public class TaskDTO {
...
private List<AbstractItemDTO> items;
}
Mapping method:
// task is an TaskDTO object
return getModelMapper().map(task, TaskEntity.class);
ModelMapper tries to create a new instance of AbstractItem, which throws an exception.
Is there a way to map the abstract classes during the runtime?
Like QuestionDTO -> Question, CriteriaDTO ->Criteria
回答1:
I also had this problem and solved this with:
public void configure(ModelMapper modelMapper) {
modelMapper.typeMap(QuestionDto.class, AbstractItem.class)
.setConverter(converterWithDestinationSupplier(Question::new));
modelMapper.typeMap(CriteriaDto.class, AbstractItem.class)
.setConverter(converterWithDestinationSupplier(Criteria::new));
}
private <S, D> Converter<S, D> converterWithDestinationSupplier(Supplier<? extends D> supplier ) {
return ctx -> ctx.getMappingEngine().map(ctx.create(ctx.getSource(), supplier.get())));
}
Converter uses supplier to create required instance and then uses right typeMap (QuestionDto -> Question or CriteriaDto -> Criteria) to map all properties.
回答2:
I couldn't solve this problem with ModelMapper. Thus, I switched over to Dozer.
Dozer is a great tool for object mapping in Java. And it is really easy to use as well.
You can define the corresponding mapping classes in a XML-file.
Here's a link to the documentation. http://dozer.sourceforge.net/documentation/mappings.html
My Solution with Spring
dozer-bean.xml
<bean class="org.dozer.spring.DozerBeanMapperFactoryBean" lazy-init="false">
<property name="mappingFiles">
<list>
<value>META-INF/mapping/dozer-config.xml</value>
</list>
</property>
</bean>
dozer-config.xml
<mapping>
<class-a>com.packagename.dto.QuestionDTO</class-a>
<class-b>com.packagename.entities.core.Question</class-b>
</mapping>
<mapping>
<class-a>com.packagename.dto.CriteriaDTO</class-a>
<class-b>com.packagename.entities.core.Criteria</class-b>
</mapping>
来源:https://stackoverflow.com/questions/28111875/modelmapper-mapping-abstract-classes-during-runtime