如何配置MapStruct在源对象所有字段为null时映射返回null
环境信息
- jdk: 17.0.1
- mapstruct: 1.5.1.Final
问题描述
默认配置下,MapStruct生成的映射代码逻辑如下:
protected AgentInfo wealthProdAccountInfoDTOToAgentInfo(WealthProdAccountInfoDTO wealthProdAccountInfoDTO) { if ( wealthProdAccountInfoDTO == null ) { return null; } String agentName = null; String agentIdentityType = null; String agentIdentityNo = null; String agentIdentityExpireAt = null; agentName = wealthProdAccountInfoDTO.getAgentName(); agentIdentityType = wealthProdAccountInfoDTO.getAgentIdentityType(); agentIdentityNo = wealthProdAccountInfoDTO.getAgentIdentityNo(); agentIdentityExpireAt = wealthProdAccountInfoDTO.getAgentIdentityExpireAt(); AgentInfo agentInfo = new AgentInfo( agentName, agentIdentityType, agentIdentityNo, agentIdentityExpireAt ); return agentInfo; }
需求为:当源对象非空,但所有待映射字段均为null时,直接返回null,不创建全属性为null的目标对象。
注:给出的期望示例代码中,全空判断逻辑写在局部变量声明之前会触发编译错误,正确的判断位置应当在所有源字段取值完成、目标对象实例化之前。
实现方案
方案1:原生注解配置(推荐,适配1.5.0+版本)
MapStruct 1.5.0及以上版本原生支持该特性,无需自定义逻辑,直接在对应映射方法上添加@BeanMapping注解,开启returnNullIfAllSourcePropertiesAreNull配置即可:
@Mapper public interface CommonMapper { @BeanMapping(returnNullIfAllSourcePropertiesAreNull = true) AgentInfo wealthProdAccountInfoDTOToAgentInfo(WealthProdAccountInfoDTO wealthProdAccountInfoDTO); }
配置后生成的代码会自动增加全字段空判断,逻辑与需求完全一致。
如果需要全局生效,不需要在每个映射方法上单独加注解,可以在MapStruct编译插件中配置全局参数,以Maven为例:
<plugin> <groupId>org.mapstruct</groupId> <artifactId>mapstruct-maven-plugin</artifactId> <version>1.5.1.Final</version> <configuration> <returnNullIfAllSourcePropertiesAreNull>true</returnNullIfAllSourcePropertiesAreNull> </configuration> </plugin>
方案2:自定义条件校验(灵活适配自定义规则)
如果需要自定义空判断规则(比如指定部分字段不参与全空校验),可以使用@Condition注解自定义判断方法,MapStruct生成代码时会自动调用该方法决定是否实例化目标对象:
@Mapper public interface CommonMapper { AgentInfo wealthProdAccountInfoDTOToAgentInfo(WealthProdAccountInfoDTO wealthProdAccountInfoDTO); // 自定义校验规则:只要存在一个非空待映射字段,就生成目标对象 @Condition default boolean hasNonEmptyMappingField(WealthProdAccountInfoDTO source) { return source.getAgentName() != null || source.getAgentIdentityType() != null || source.getAgentIdentityNo() != null || source.getAgentIdentityExpireAt() != null; } }
该方式兼容更低版本MapStruct,可灵活调整判断逻辑。
内容的提问来源于stack exchange,提问作者fjy8018
相关产品推荐
相关产品推荐

