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

Mapstruct映射Kotlin不可变嵌套对象时如何传递父对象属性值

你之前的写法失效,核心是两个原因叠加:

  1. MapStruct处理businessCard.text这种嵌套属性映射时,会先生成独立的子映射方法完成BusinessCard到BusinessCardDto的转换,该方法的入参只有BusinessCard,无法访问外层的Worker实例
  2. 你的DTO是不可变对象,所有属性只能在构造时赋值,无法像可变对象那样在生成子实例后再追加赋值父对象字段

以下是两种不需要使用@AfterMapping的可行实现方案:

方案1:自定义多参数子映射方法

直接定义接收完整Worker对象的子映射逻辑,由你自己控制BusinessCardDto的构造:

@Mapper(config = CustomMappingConfig::class, uses = [ComputerMapper::class])
abstract class WorkerMapper {

    // 直接指定businessCard字段的源为整个worker对象
    @Mapping(target = "businessCard", source = "worker")
    abstract fun mapWorker(worker: Worker): WorkerDto

    // 自定义子映射逻辑,拿到完整worker对象后构造BusinessCardDto
    protected fun mapBusinessCard(worker: Worker): BusinessCardDto? {
        val businessCard = worker.businessCard ?: return null
        return BusinessCardDto("${worker.name} | ${businessCard.companyName}")
    }
}

这种方案的优势是逻辑清晰,纯Kotlin实现不需要写Java表达式,后续维护成本低。

方案2:在表达式中直接构造子对象

如果你不想额外写子映射方法,也可以直接在表达式中完成BusinessCardDto的构造:

@Mapper(config = CustomMappingConfig::class, uses = [ComputerMapper::class])
abstract class WorkerMapper {

    @Mapping(
        target = "businessCard",
        expression = "java( worker.getBusinessCard() == null ? null : new BusinessCardDto( worker.getName() + \" | \" + worker.getBusinessCard().getCompanyName() ) )"
    )
    abstract fun mapWorker(worker: Worker): WorkerDto
}

生成的代码会直接在WorkerDto的构造逻辑中完成BusinessCardDto的创建,不会生成独立的子映射方法,自然不存在变量作用域问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 23:24:06