关于MapStruct使用expression表达式的小坑

最近项目中使用了mapStruct进行对象属性拷贝,关于使用方式和原理不做赘述,可自行查找!

最近在使用中发现了mapStruct框架的一个小坑,在我们使用expression来指定处理source中的某个属性后设置到target对象的某个属性中的时,会出某种异常现象

如:

@Override
@Mappings({
      @Mapping(source = "leaveLesson", target = "hadLesson"),
      @Mapping(source = "quitPrice", target = "retireAmount"),
      @Mapping(source = "createdDate", target = "retireTime"),
      @Mapping(expression = "java(parseToRetireApplyStatus(applyBillInfoRes.getBillState()))", target = "retireApplyStatus")
})
RetireApplyRecordInfoVo convert(RetireApplyBillInfoRes applyBillInfoRes);

编译后的class:

    @Override
    public RetireApplyRecordInfoVo convert(RetireApplyBillInfoRes applyBillInfoRes) {
        if ( applyBillInfoRes == null ) {
            return null;
        }

        RetireApplyRecordInfoVo retireApplyRecordInfoVo = new RetireApplyRecordInfoVo();

        retireApplyRecordInfoVo.setHadLesson( parseToRetireApplyStatus( applyBillInfoRes.getLeaveLesson() ) );
        retireApplyRecordInfoVo.setRetireTime( applyBillInfoRes.getCreatedDate() );
        retireApplyRecordInfoVo.setRetireAmount( applyBillInfoRes.getQuitPrice() );
        retireApplyRecordInfoVo.setClassCode( applyBillInfoRes.getClassCode() );
        retireApplyRecordInfoVo.setCardCode( applyBillInfoRes.getCardCode() );
        retireApplyRecordInfoVo.setBillCode( applyBillInfoRes.getBillCode() );

        retireApplyRecordInfoVo.setRetireApplyStatus( parseToRetireApplyStatus(applyBillInfoRes.getBillState()) );

        return retireApplyRecordInfoVo;
    }

可以明显看到我只想处理 retireApplyStatus ,但是hadLesson 也经过了同样的方法处理。

 

于是做出猜想:是不是由于target类型与source类型两两一致才会这样?

做出如下修改,将parseToRetireApplyStatus方法的参数改为String类型并随便赋值一个String类型属性:

        @Override
        @Mappings({
                @Mapping(source = "leaveLesson", target = "hadLesson"),
                @Mapping(source = "quitPrice", target = "retireAmount"),
                @Mapping(source = "createdDate", target = "retireTime"),
                @Mapping(expression = "java(parseToRetireApplyStatus(applyBillInfoRes.getStudentCode()))", target = "retireApplyStatus")
        })
        RetireApplyRecordInfoVo convert(RetireApplyBillInfoRes applyBillInfoRes);

编译后:

    @Override
    public RetireApplyRecordInfoVo convert(RetireApplyBillInfoRes applyBillInfoRes) {
        if ( applyBillInfoRes == null ) {
            return null;
        }

        RetireApplyRecordInfoVo retireApplyRecordInfoVo = new RetireApplyRecordInfoVo();

        retireApplyRecordInfoVo.setHadLesson( applyBillInfoRes.getLeaveLesson() );
        retireApplyRecordInfoVo.setRetireTime( applyBillInfoRes.getCreatedDate() );
        retireApplyRecordInfoVo.setRetireAmount( applyBillInfoRes.getQuitPrice() );
        retireApplyRecordInfoVo.setClassCode( applyBillInfoRes.getClassCode() );
        retireApplyRecordInfoVo.setCardCode( applyBillInfoRes.getCardCode() );
        retireApplyRecordInfoVo.setBillCode( applyBillInfoRes.getBillCode() );

        retireApplyRecordInfoVo.setRetireApplyStatus( parseToRetireApplyStatus(applyBillInfoRes.getStudentCode()) );

        return retireApplyRecordInfoVo;
    }

明显这样就没有了对 leaveLesson->hadLesson 的类似处理。

那么这个问题应该如何解决呢?有两种方案,一是不适用expression,特殊字段在外面进行处理;二是,对发生冲突的字段leaveLesson也进行expression表达式处理,不过这种方式要冲突的字段有多少个了,视情况选择不同的处理方式吧!

我采用的后者:

        @Override
        @Mappings({
                @Mapping(expression = "java(applyBillInfoRes.getLeaveLesson())", target = "hadLesson"),
                @Mapping(source = "quitPrice", target = "retireAmount"),
                @Mapping(source = "createdDate", target = "retireTime"),
                // 注意当前Integer属性使用expression进行处理后,mapStruct自动生成代码中所有的Integer类型属性都会经过同样表达式处理,所以上面hadLesson字段也进行了expression指定
                @Mapping(expression = "java(parseToRetireApplyStatus(applyBillInfoRes.getBillState()))", target = "retireApplyStatus")
        })
        RetireApplyRecordInfoVo convert(RetireApplyBillInfoRes applyBillInfoRes);

编译后:

    @Override
    public RetireApplyRecordInfoVo convert(RetireApplyBillInfoRes applyBillInfoRes) {
        if ( applyBillInfoRes == null ) {
            return null;
        }

        RetireApplyRecordInfoVo retireApplyRecordInfoVo = new RetireApplyRecordInfoVo();

        retireApplyRecordInfoVo.setRetireTime( applyBillInfoRes.getCreatedDate() );
        retireApplyRecordInfoVo.setRetireAmount( applyBillInfoRes.getQuitPrice() );
        retireApplyRecordInfoVo.setClassCode( applyBillInfoRes.getClassCode() );
        retireApplyRecordInfoVo.setCardCode( applyBillInfoRes.getCardCode() );
        retireApplyRecordInfoVo.setBillCode( applyBillInfoRes.getBillCode() );

        retireApplyRecordInfoVo.setHadLesson( applyBillInfoRes.getLeaveLesson() );
        retireApplyRecordInfoVo.setRetireApplyStatus( parseToRetireApplyStatus(applyBillInfoRes.getBillState()) );

        return retireApplyRecordInfoVo;
    }

符合预期!具体原因待后续研究后补充!

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 11
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值