ModelMapper:混合隐式和显式映射?

时间:2014-12-19 09:53:31

标签: java modelmapper

为了编写所需的最少代码量,我试图让ModelMapper生成其隐式映射,并且只为那些无法自动映射的属性编写显式属性映射。

如果我让ModelMapper使用:

生成隐式映射
modelMapper.createTypeMap(SourceType.class, DestType.class);

它抱怨setSomeId有多个可能的映射。然后我尝试使用以下方法解决这个问题:

modelMapper.addMappings(new PropertyMap<SourceType, DestType>() {
    protected void configure() {
        map().setSomeId(source.getProperty().getWeirdID());
    }
});

然而,我发现ModelMapper仍然抱怨,因为createTypeMap实际上抛出了异常,所以它没有机会到达我的自定义映射代码。

如果我反转两个语句,我会收到错误:

  

java.lang.IllegalStateException:类SourceMap和类DestType已存在TypeType

如果我完全忽略createTypeMap,ModelMapper会抱怨DestType的所有其他属性(那些能够使用createTypeMap自动映射的人)缺少映射。

我在文档中没有找到明确的线索,是否支持使用显式映射混合以及如何完成。

有人可以帮忙吗?

3 个答案:

答案 0 :(得分:1)

而不是ModelMapper.createTypeMap尝试ModelMapper.addMappings(第一个)。这仍会创建(并返回)TypeMap,但在执行此操作时会考虑您的PropertyMap

答案 1 :(得分:1)

不知道这对你来说是否还是个问题,我必须承认我是ModelMapper的新手。从来没有遇到过你曾经遇到过的同样问题。我好像已经解决了。

    TypeMap<RateDTO, Rate> rateDTORateTypeMap = modelMapper.getTypeMap(RateDTO.class, Rate.class);
    if(rateDTORateTypeMap == null) {
        rateDTORateTypeMap = modelMapper.createTypeMap(RateDTO.class, Rate.class);
    }
    rateDTORateTypeMap.setProvider(request -> {
        RateDTO source = RateDTO.class.cast(request.getSource());
        CurrencyAndAmount price = new CurrencyAndAmount(source.getPrice().getCurrencyCode(), source.getPrice().getAmount());
        return new Rate(price, source.getPaymentDate(), source.getPaymentId());
    });

基本上我首先尝试获取TypeMap,如果它已经存在,否则我创建一个新的/修改过的映射。

希望有所帮助

答案 2 :(得分:1)

假设我们要将Source source映射到Destination destination。 代替

Destination destination = modelMapper.map(source, Destination.class);

为了结合显式和隐式映射,我们将implicitMappings()添加到TypeMap

public Destination mapSourceToDestination(Source source) {
            TypeMap<Source, Destination> typeMap = modelMapper
                    .typeMap(Source.class, Destination.class)
                    .implicitMappings()
                    .addMappings(mapper -> {
                        mapper.map(source -> source.getPropetryOne().getSubPropetryOne(), Destination::setPropetryA);
                    });
            return typeMap.map(source);
        }