MapStruct使用映射对象作为入参生成代码抛UnsupportedOperationException问题
问题根因
- 你用到的
PredictionRequest和Destination都是Protobuf生成的类,MapStruct内置了Protobuf类型的专属映射逻辑,默认会自动同步两个Protobuf对象的unknownFields以及allFields集合 - Protobuf生成的
getAllFields()方法返回的是不可变Map,不支持putAll操作,所以执行时直接抛出UnsupportedOperationException - 当传入非映射生成的对象时,MapStruct识别不到对应Protobuf字段的匹配逻辑,就不会生成这段同步代码,因此不会报错
解决方案
方案1:针对当前Mapper方法单独忽略系统字段
直接在PredictionMapper的map方法上追加两个忽略字段的注解即可,改完重新编译后生成的代码就只会保留你需要的setDestination逻辑:
@Mapping(source = "request.idOrder", target = "referenceId") @Mapping(source = "request.orderDateUTC", target = "expeditionDate") @Mapping(source = "protoDestination", target = "destination") @Mapping(source = "notDeliverableLocalDates", target = "notDeliverableLocalDatesList") // 追加以下两行,忽略Protobuf自动同步的系统字段 @Mapping(target = "unknownFields", ignore = true) @Mapping(target = "allFields", ignore = true) PredictionRequest map(Request request, List<String> notDeliverableLocalDates, Destination protoDestination);
方案2:全局关闭Protobuf字段自动同步逻辑
如果项目里多处都有同类问题,可以全局关闭MapStruct的Protobuf自动字段同步配置,无需每个Mapper单独配置,在maven-compiler-plugin编译参数中添加以下配置即可:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <source>11</source> <target>11</target> <annotationProcessorPaths> <path> <groupId>org.mapstruct</groupId> <artifactId>mapstruct-processor</artifactId> <version>你的MapStruct版本号</version> </path> </annotationProcessorPaths> <compilerArgs> <!-- 全局关闭Protobuf自动同步字段逻辑 --> <arg>-Amapstruct.protobuf.auto-configure-fields=false</arg> </compilerArgs> </configuration> </plugin>
方案3:严格控制只映射指定字段
如果需要完全避免MapStruct自动生成未明确声明的映射逻辑,可以给方法加上@BeanMapping(ignoreByDefault = true),只有你标注的@Mapping规则才会生效:
@BeanMapping(ignoreByDefault = true) @Mapping(source = "request.idOrder", target = "referenceId") @Mapping(source = "request.orderDateUTC", target = "expeditionDate") @Mapping(source = "protoDestination", target = "destination") @Mapping(source = "notDeliverableLocalDates", target = "notDeliverableLocalDatesList") PredictionRequest map(Request request, List<String> notDeliverableLocalDates, Destination protoDestination);
内容的提问来源于stack exchange,提问作者Roberto Rodriguez
相关产品推荐
相关产品推荐

