最近项目中使用了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(()))", target = "retireApplyStatus")
})
RetireApplyRecordInfoVo convert(RetireApplyBillInfoRes applyBillInfoRes);
编译后的class:
@Override
public RetireApplyRecordInfoVo convert(RetireApplyBillInfoRes applyBillInfoRes) {
if ( applyBillInfoRes == null ) {
return null;
}
RetireApplyRecordInfoVo retireApplyRecordInfoVo = new RetireApplyRecordInfoVo();
( parseToRetireApplyStatus( () ) );
( () );
( () );
( () );
( () );
( () );
( parseToRetireApplyStatus(()) );
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(()))", target = "retireApplyStatus")
})
RetireApplyRecordInfoVo convert(RetireApplyBillInfoRes applyBillInfoRes);
编译后:
@Override
public RetireApplyRecordInfoVo convert(RetireApplyBillInfoRes applyBillInfoRes) {
if ( applyBillInfoRes == null ) {
return null;
}
RetireApplyRecordInfoVo retireApplyRecordInfoVo = new RetireApplyRecordInfoVo();
( () );
( () );
( () );
( () );
( () );
( () );
( parseToRetireApplyStatus(()) );
return retireApplyRecordInfoVo;
}
明显这样就没有了对 leaveLesson->hadLesson 的类似处理。
那么这个问题应该如何解决呢?有两种方案,一是不适用expression,特殊字段在外面进行处理;二是,对发生冲突的字段leaveLesson也进行expression表达式处理,不过这种方式要冲突的字段有多少个了,视情况选择不同的处理方式吧!
我采用的后者:
@Override
@Mappings({
@Mapping(expression = "java(())", target = "hadLesson"),
@Mapping(source = "quitPrice", target = "retireAmount"),
@Mapping(source = "createdDate", target = "retireTime"),
// 注意当前Integer属性使用expression进行处理后,mapStruct自动生成代码中所有的Integer类型属性都会经过同样表达式处理,所以上面hadLesson字段也进行了expression指定
@Mapping(expression = "java(parseToRetireApplyStatus(()))", target = "retireApplyStatus")
})
RetireApplyRecordInfoVo convert(RetireApplyBillInfoRes applyBillInfoRes);
编译后:
@Override
public RetireApplyRecordInfoVo convert(RetireApplyBillInfoRes applyBillInfoRes) {
if ( applyBillInfoRes == null ) {
return null;
}
RetireApplyRecordInfoVo retireApplyRecordInfoVo = new RetireApplyRecordInfoVo();
( () );
( () );
( () );
( () );
( () );
( () );
( parseToRetireApplyStatus(()) );
return retireApplyRecordInfoVo;
}
符合预期!具体原因待后续研究后补充!