【问题标题】:ModelMapper: mapping abstract classes during runtimeModelMapper:在运行时映射抽象类
【发布时间】:2015-03-22 14:36:10
【问题描述】:

我正在使用 ModelMapper 框架 (http://modelmapper.org/) 在 Java 中映射对象。 我在映射包含抽象类的具体类(DTO 到实体)时遇到了问题。

示例: 任务有一个 AbstractItems 列表。
AbstractItems 是问题和标准。

public class TaskDTO {
   ...
   private List<AbstractItemDTO> items;
}

映射方法:

// task is an TaskDTO object
return getModelMapper().map(task, TaskEntity.class);

ModelMapper 尝试创建一个新的 AbstractItem 实例,这会引发异常。 有没有办法在运行时映射抽象类?
Like QuestionDTO -> Question, CriteriaDTO ->Criteria

【问题讨论】:

    标签: java object-object-mapping modelmapper


    【解决方案1】:

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

    这是文档的链接。 http://dozer.sourceforge.net/documentation/mappings.html

    我的 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>
    

    【讨论】:

      【解决方案2】:

      我也遇到了这个问题,解决了这个问题:

      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 使用供应商创建所需的实例,然后使用正确的 typeMap (QuestionDto -> Question 或 CriteriaDto -> Criteria) 映射所有属性。

      【讨论】:

        【解决方案3】:

        在哪里使用 ModelMapper 的 kotlin 解决方案

        DTO(又名源类)

        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) }
        

        ModelMapper 版本:2.3.7

        https://github.com/modelmapper/modelmapper/issues/182#issuecomment-660965119

        【讨论】:

          猜你喜欢
          • 2020-04-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-08-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多