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

Mapstruct结合Lombok @Builder多源嵌套对象映射问题

MapStruct + Lombok @Builder 多源映射嵌套字段未填充问题解决

问题场景

使用MapStruct从JmsMessageKpiDto和KpiDto两个源对象构建带嵌套KpiMeta的Kpi对象,Kpi和KpiMeta均使用Lombok的@Builder注解。已通过@Mapper(uses = KpiMetaMapper.class)引入负责生成KpiMeta的映射器,但生成的代码中Kpi的meta字段始终未被填充。

可行解决方案

1. 显式指定嵌套字段的映射规则

在KpiMapper的映射方法中,通过@Mapping注解明确指定meta字段的映射逻辑,调用KpiMetaMapper中的多参数映射方法:

首先给KpiMetaMapper的映射方法添加@Named标识:

@Mapper
interface KpiMetaMapper {
    KpiMetaMapper INSTANCE = Mappers.getMapper(KpiMetaMapper.class);

    @Named("toKpiMeta")
    KpiMeta toKpiMeta(JmsMessageKpiDto jms, KpiDto dto);
}

然后在KpiMapper中关联该方法:

@Mapper(uses = KpiMetaMapper.class)
interface KpiMapper {
    KpiMapper INSTANCE = Mappers.getMapper(KpiMapper.class);

    @Mapping(target = "name", source = "dto.name")
    @Mapping(target = "meta", source = ".", qualifiedByName = "toKpiMeta")
    Kpi toKpi(JmsMessageKpiDto jms, KpiDto dto);
}

这里source = "."表示将所有源参数(即jms和dto)传递给qualifiedByName指定的方法,MapStruct会自动匹配参数类型完成映射。

2. 调整Kpi的Builder配置(避免Builder冲突)

MapStruct在处理Lombok的@Builder时,有时会因为Builder的参数顺序或默认生成逻辑导致嵌套字段映射失效。可以给Kpi类的@Builder添加toBuilder = true,确保MapStruct能正确触发Builder的字段填充逻辑:

@Builder(toBuilder = true)
class Kpi {
    String name;
    KpiMeta meta;
}

3. 已验证有效的@AfterMapping兜底方案

如果上述方案不适用,@AfterMapping是最直接的兜底方案,手动在映射后填充meta字段:

@Mapper(uses = KpiMetaMapper.class)
interface KpiMapper {
    KpiMapper INSTANCE = Mappers.getMapper(KpiMapper.class);

    @Mapping(target = "meta", ignore = true)
    Kpi toKpi(JmsMessageKpiDto jms, KpiDto dto);

    @AfterMapping
    default void fillKpiMeta(JmsMessageKpiDto jms, KpiDto dto, @MappingTarget Kpi.KpiBuilder kpiBuilder) {
        kpiBuilder.meta(KpiMetaMapper.INSTANCE.toKpiMeta(jms, dto));
    }
}

这里先忽略meta的自动映射,再通过@AfterMapping调用KpiMetaMapper的方法,手动给Builder设置meta字段。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 08:07:40