ModelMapper: mapping abstract classes during runtime

后端 未结 3 655
南旧
南旧 2020-12-19 08:31

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

相关标签:
3条回答
  • 2020-12-19 09:02

    Where a kotlin solution with ModelMapper

    DTOs (aka source class)

    abstract class BaseRequirementDTO()
    class AttributeRequirementDTO(
    
            var attribute: Attribute = Attribute.STRENGTH,
            var attributeValue: Long = 10
    
    ) : BaseRequirementDTO()
    class LevelRequirementDTO(
    
            var requiredLevel: Long = 1
    
    ) : BaseRequirementDTO()
    

    My Models (aka destination class)

    abstract class BaseRequirement() : Model()
    class AttributeRequirement(
    
            var attribute: Attribute = Attribute.STRENGTH,
            var attributeValue: Long = 10
    
    ) : BaseRequirement()
    class LevelRequirement(
    
            var requiredLevel: Long = 1
    
    ) : BaseRequirement()
    

    Mapper configuration

    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 version: 2.3.7

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

    0 讨论(0)
  • 2020-12-19 09:13

    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.

    0 讨论(0)
  • 2020-12-19 09:17

    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>
    
    0 讨论(0)
提交回复
热议问题