Mapstruct映射Kotlin不可变嵌套对象时如何传递父对象属性值
你之前的写法失效,核心是两个原因叠加:
- MapStruct处理
businessCard.text这种嵌套属性映射时,会先生成独立的子映射方法完成BusinessCard到BusinessCardDto的转换,该方法的入参只有BusinessCard,无法访问外层的Worker实例 - 你的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
相关产品推荐
相关产品推荐

