能否通过MapStruct实现从Object到Map的@MappingTarget映射更新?
MapStruct实现指定字段更新Map的可行性方案
问题描述
我的应用中实体包含大量JSON字段,因此仅需更新已知字段。以下是我的代码示例:
@Mapper( config = CommonMapper.class, nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE, nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS) public interface ProductMapper { @Mapping(target = "id", source = "id") // 此配置未生效 void updateMapFromProduct(@MappingTarget Map<String, Object> map, Product product); }
我希望生成如下形式的ProductMapperImpl实现类,请问是否可行?
@Generated( value = "org.mapstruct.ap.MappingProcessor", date = "2022-09-02T10:04:50+0900", comments = "version: 1.4.2.Final, compiler: IncrementalProcessingEnvironment from gradle-language-java-7.5.jar, environment: Java 11.0.11 (AdoptOpenJDK)" ) @Component public class ProductMapperImpl implements ProductMapper { @Override public void updateMapFromProduct(Map<String, Object> map, Product product) { if ( map == null ) { return; } map.put("id", product.getId()); } }
解决方案
可行,但需要调整Mapper配置,让MapStruct生成你想要的代码。
问题根源
当前@Mapping配置未生效,是因为MapStruct默认处理Map类型时会尝试映射所有可访问属性,而非仅你指定的字段;再加上继承了CommonMapper的全局规则,进一步干扰了当前方法的映射逻辑。
调整步骤
- 开启默认忽略未指定字段:在映射方法上添加
@BeanMapping(ignoreByDefault = true),这样MapStruct只会处理你显式声明的字段映射,忽略其他所有属性。 - 保留指定字段映射:保留原有的
@Mapping(target = "id", source = "id")配置,确保仅更新id字段。
修改后的Mapper代码:
@Mapper( config = CommonMapper.class, nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE, nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS) public interface ProductMapper { @BeanMapping(ignoreByDefault = true) @Mapping(target = "id", source = "id") void updateMapFromProduct(@MappingTarget Map<String, Object> map, Product product); }
生成效果
调整后,MapStruct会生成完全符合你期望的实现类:
- 保留对
map的null值校验 - 仅执行
map.put("id", product.getId())操作,不会处理其他未指定的字段
内容的提问来源于stack exchange,提问作者Joonseo Lee
相关产品推荐
相关产品推荐

