Java ModelMapper:在运行时映射抽象类

Java ModelMapper:在运行时映射抽象类,java,object-object-mapping,modelmapper,Java,Object Object Mapping,Modelmapper,我使用ModelMapper Framework()在Java中映射对象。 我在映射包含抽象类的具体类(DTO到Entite)时遇到了一个问题 例如: 任务有一个抽象项列表 抽象项目是问题和标准 public class TaskDTO { ... private List<AbstractItemDTO> items; } ModelMapper尝试创建AbstractItem的新实例,该实例引发异常。 有没有办法在运行时映射抽象类? 像QuestionDTO->Qu

我使用ModelMapper Framework()在Java中映射对象。 我在映射包含抽象类的具体类(DTO到Entite)时遇到了一个问题

例如: 任务有一个抽象项列表
抽象项目是问题和标准

public class TaskDTO {
   ...
   private List<AbstractItemDTO> items;
}
ModelMapper尝试创建AbstractItem的新实例,该实例引发异常。 有没有办法在运行时映射抽象类?

像QuestionDTO->Question,CriteriaDTO->Criteria

我无法用ModelMapper解决这个问题。因此,我切换到推土机
Dozer是Java中用于对象映射的伟大工具。而且它也很容易使用。 可以在XML文件中定义相应的映射类

这里是文档的链接

我的春天解决方案
dozer-bean.xml


META-INF/mapping/dozer-config.xml
dozer-config.xml


com.packagename.dto.QuestionDTO
com.packagename.entities.core.Question
com.packagename.dto.CriteriaDTO
com.packagename.entities.core.Criteria

我也遇到了这个问题,并通过以下方法解决了这个问题:

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()));
}
public void配置(ModelMapper ModelMapper){
typeMap(QuestionDto.class,AbstractItem.class)
.setConverter(带目标供应商的转换器(问题::新建));
typeMap(CriteriaDto.class,AbstractItem.class)
.setConverter(带目标供应商的转换器(标准::新建));
}

带有目标供应商的专用转换器转换器(供应商使用ModelMapper的kotlin解决方案

DTO(又名源类)

我的模型(又名目的地类)

映射器配置

val mapper = ModelMapper()
mapper.configuration.matchingStrategy = MatchingStrategies.STRICT
mapper.createTypeMap(BaseRequirement::class.java, BaseRequirementDTO::class.java)
mapper.typeMap(AttributeRequirementDTO::class.java, BaseRequirement::class.java)
        .setProvider { request -> mapper.map(request.source, AttributeRequirement::class.java) }
mapper.typeMap(LevelRequirementDTO::class.java, BaseRequirement::class.java)
        .setProvider { request -> mapper.map(request.source, LevelRequirement::class.java) }
ModelMapper版本:2.3.7

<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>
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()));
}
abstract class BaseRequirementDTO()
class AttributeRequirementDTO(

        var attribute: Attribute = Attribute.STRENGTH,
        var attributeValue: Long = 10

) : BaseRequirementDTO()
class LevelRequirementDTO(

        var requiredLevel: Long = 1

) : BaseRequirementDTO()
abstract class BaseRequirement() : Model()
class AttributeRequirement(

        var attribute: Attribute = Attribute.STRENGTH,
        var attributeValue: Long = 10

) : BaseRequirement()
class LevelRequirement(

        var requiredLevel: Long = 1

) : BaseRequirement()
val mapper = ModelMapper()
mapper.configuration.matchingStrategy = MatchingStrategies.STRICT
mapper.createTypeMap(BaseRequirement::class.java, BaseRequirementDTO::class.java)
mapper.typeMap(AttributeRequirementDTO::class.java, BaseRequirement::class.java)
        .setProvider { request -> mapper.map(request.source, AttributeRequirement::class.java) }
mapper.typeMap(LevelRequirementDTO::class.java, BaseRequirement::class.java)
        .setProvider { request -> mapper.map(request.source, LevelRequirement::class.java) }