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

MapStruct使用@Context传递上下文属性报错:No property named 'myContext1.param1' exists的解决咨询

MapStruct使用@Context传递上下文属性报错:No property named 'myContext1.param1' exists的解决咨询

嘿,我来帮你捋清楚这个问题的根源和解决办法~

首先,你遇到的报错原因很明确:MapStruct的@Context注解标记的参数,默认是作为映射上下文来使用的,不是用来直接当作映射源的属性容器。所以你直接在@Mapping的source里写myContext1.param1时,MapStruct只会去主源对象(也就是这里的MySource)里找属性,自然找不到myContext1.param1这个路径啦。

接下来给你两种可行的解决思路,你可以根据自己的场景选:

方案一:用@AfterMapping手动注入上下文属性

这种方式保留@Context的用法,先让MapStruct自动映射主源对象的属性,再通过@AfterMapping方法把上下文里的属性手动赋值给目标对象:

@Mapper
interface MyMapper {
    // 先映射MySource里的name属性
    @Mapping(target = "name", source = "name")
    fun mapMy(
        mySource: MySource,
        @Context myContext1: MyContext1,
        @Context myContext2: MyContext2
    ): MyTarget

    // 用@AfterMapping在自动映射完成后,补充上下文属性
    @AfterMapping
    fun setContextProperties(
        @MappingTarget target: MyTarget,
        @Context myContext1: MyContext1,
        @Context myContext2: MyContext2
    ) {
        target.param1 = myContext1.param1
        target.param2 = myContext2.param2
    }
}

方案二:去掉@Context,把上下文参数当作普通源参数

如果这些参数只是用来提供映射所需的属性,不需要利用@Context在嵌套映射中传递上下文的特性,那直接去掉@Context注解,让MapStruct把它们当作普通的源参数处理,此时需要在@Mapping里明确指定参数名.属性名:

@Mapper
interface MyMapper {
    @Mapping(target = "name", source = "mySource.name")
    @Mapping(target = "param1", source = "myContext1.param1")
    @Mapping(target = "param2", source = "myContext2.param2")
    fun mapMy(
        mySource: MySource,
        myContext1: MyContext1,
        myContext2: MyContext2
    ): MyTarget
}

关于你提到的QualifiedByName示例的区别

你说的那个多参数QualifiedByName示例,@Context的用法是给自定义的转换方法传递额外参数,而不是直接在@Mapping的source里引用上下文属性。举个类似的例子:

@Mapper
interface MyMapper {
    // 把MySource的name交给自定义方法转换,同时传递上下文参数
    @Mapping(target = "param1", source = "name", qualifiedByName = "generateParam1")
    fun mapMy(
        mySource: MySource,
        @Context myContext1: MyContext1
    ): MyTarget

    // 自定义方法接收源属性和上下文参数,生成目标属性值
    @Named("generateParam1")
    fun generateParam1(sourceName: String, @Context context: MyContext1): String {
        return "${sourceName}_${context.param1}"
    }
}

这里@Context是用来给@Named标记的自定义转换方法传参的,和你直接在@Mapping里引用上下文属性的用法完全不同,这就是两者的核心区别啦。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.07 11:13:07