You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中如何配置ModelMapper跳过对象内的Null对象映射?

问题分析

你遇到的核心问题是ModelMapper的map方法使用错误,同时对setSkipNullEnabled(true)的生效逻辑理解有偏差:

  1. 你预先通过newInstance()创建了带有嵌套空DTO实例的initializedFilterDto,但随后用modelMapper.map(filterDto, OperationDto.class)创建了全新的OperationDto对象,直接覆盖了之前初始化的实例,导致预先创建的嵌套空对象全部丢失。
  2. 当源对象filterDto中的嵌套属性(如driverDto)为null时,新创建的目标对象对应属性会被设置为null,这就是你看到的“源Null对象被映射到目标”的现象。

解决方案

方案一:使用更新式映射(保留目标对象原有值)

修改映射逻辑,将源对象的属性映射到已初始化的目标对象上,而非创建新对象。此时setSkipNullEnabled(true)会生效:源对象的null属性不会覆盖目标对象已有的嵌套空实例。

public List<OperationDto> getAllByFilter(OperationDto filterDto) throws TalyumException {
    // 初始化带有嵌套空实例的目标对象
    OperationDto initializedFilterDto = (OperationDto) new OperationDto().newInstance();

    // 配置ModelMapper:跳过源的null属性,保留目标原有值
    modelMapper.getConfiguration().setSkipNullEnabled(true);
    modelMapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT);        
    // 关键:将源对象映射到已存在的目标对象,而非创建新实例
    modelMapper.map(filterDto, initializedFilterDto);

    List<OperationEntity> operationEntityList = operationRepository.findAllByFilter(initializedFilterDto);
    return operationEntityList.stream().map(entity -> modelMapper.map(entity, OperationDto.class)).toList();
}

方案二:自定义转换器(自动初始化嵌套DTO)

如果希望所有OperationDto实例在创建时自动初始化嵌套对象,无需手动调用newInstance(),可以给ModelMapper添加自定义转换器:

// 在ModelMapper配置类中添加转换器(确保ModelMapper是单例)
modelMapper.addConverter(new Converter<OperationEntity, OperationDto>() {
    @Override
    public OperationDto convert(MappingContext<OperationEntity, OperationDto> context) {
        OperationDto dto = new OperationDto();
        // 自动初始化所有嵌套DTO
        dto.setDriverDto(new UserDto());
        dto.setOperatorDto(new UserDto());
        dto.setVehicleDto(new VehicleDto());
        dto.setFromLocationDto(new LocationDto());
        dto.setToLocationDto(new LocationDto());
        // 让ModelMapper完成剩余属性的映射
        modelMapper.map(context.getSource(), dto);
        return dto;
    }
});

注意事项

  • setSkipNullEnabled(true)仅对源对象的null属性生效:当源属性为null时,不会覆盖目标对象的对应属性值;如果源属性有值,会正常覆盖目标属性。
  • 确保ModelMapper是单例实例(如Spring环境中用@Bean注入),避免每次方法调用重复创建导致配置失效。

内容的提问来源于stack exchange,提问作者Akcan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 03:51:16