mapstruct和lombok编译出错,No property named “xxx” exists in source parameter(s). Did you mean “null”

在项目中遇到MapStruct和Lombok配合使用时出现编译错误,提示找不到属性。问题源于编译顺序和版本不兼容。通过升级到lombok版本1.18.10和mapstruct版本1.3.0.Final,以及添加对应的依赖,可以成功解决属性找不到的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

项目场景:

mapstruct和lombok编译出错,提示属性找不到

报错No property named “XXX“ exists in source parameter(s). Did you mean “null“


问题描述:


原因分析:

由于mapstruct先编译,lombok后编译,导致类里面的属性找不到,找到原因是版本问题


解决方案:

使用这两个的版本就可解决

<lombok.version>1.18.10</lombok.version>
<mapstruct.version>1.3.0.Final</mapstruct.version>

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>${lombok.version}</version>
</dependency>
<dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct-jdk8</artifactId>
    <version>${mapstruct.version}</version>
</dependency>
<dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct-processor</artifactId>
    <version>${mapstruct.version}</version>
</dependency>

 

<think>我们正在处理一个MyBatis框架中常见的错误:"There is no getter for property named 'xxx' in 'class com.xxx.xxx'" 这个错误通常发生在MyBatis试图访问一个JavaBean的属性时,但该JavaBean没有对应的getter方法。 根据引用[1][2][3][4],我们可以总结出以下几种情况: 1. 在MyBatis的XML映射文件中,我们使用了某个属性(例如`property="xxx"`),但是对应的JavaBean(实体类)中没有为这个属性提供getter方法。 2. 可能属性名写错了(比如大小写问题,或者拼写错误)。 3. 实体类中的字段命名不符合JavaBean规范(例如,字段是私有的,但没有提供public的getter方法)。 4. 在动态SQL中使用变量时,变量名实体类的属性名不一致。 解决方案: 1. 检查JavaBean(实体类)中是否确实存在该属性,并且属性名与XML中引用的名称完全一致(注意大小写)。 2. 如果存在该属性,确保提供了public的getter方法。方法名应该是`getXxx()`(对于布尔类型,可以是`isXxx()`)。 3. 检查MyBatis的XML文件中使用该属性的地方,确保没有拼写错误。 4. 如果属性名由多个单词组成,确保getter方法遵循驼峰命名法。例如,属性名为`userName`,则getter方法应为`getUserName()`。 5. 如果使用了Lombok等自动生成getter/setter的工具,确保注解(如`@Data`)被正确使用,并且编译后确实生成了相应的方法。 6. 重新生成实体类、Mapper文件等(如引用[4]所建议),但注意不要手动修改实体类中已经由工具生成的代码。 具体步骤: 假设错误信息是:There is no getter for property named 'SKUCODE' in 'class com.fedex.ecommerce.imp.c.entrymanager.application.domain.aggregate.HsCode' 步骤1:打开HsCode类,检查是否有名为`SKUCODE`的属性(字段)。注意,在Java中,属性名通常采用驼峰命名法,所以可能是`skucode`或`skuCode`。 步骤2:如果存在该字段,检查是否有getter方法:`public String getSkuCode()`(假设类型为String)或者`public String getSKUCODE()`?注意,按照JavaBean规范,getter方法应该是`getSkuCode`(如果字段名为`skuCode`)或`getSkucode`(如果字段名为`skucode`)。但是,如果字段名为`SKUCODE`(全大写),那么getter方法应该是`getSKUCODE()`。然而,通常不推荐使用全大写的字段名。 步骤3:如果字段名是`skuCode`,那么MyBatis在XML中引用时应该使用`skuCode`(注意大小写)。如果XML中写成了`SKUCODE`,那么MyBatis会找不到,因为默认情况下MyBatis是区分大小写的。 步骤4:如果确定是字段命名规范问题,可以尝试修改实体类,将字段名改为符合驼峰命名法(如`skuCode`),并提供相应的getter方法,然后在XML中使用`skuCode`。 另一种解决方案(不推荐修改实体类时): 如果无法修改实体类(比如是第三方类),可以在MyBatis的XML映射文件中使用`<resultMap>`来映射字段属性,或者使用`@Param`注解(在接口方法中)来指定参数名。 例如,在动态SQL中: 错误写法:`<if test="SKUCODE != null">` 如果实体类中没有`SKUCODE`的getter,就会报错。 正确写法:如果实体类中的字段是`skuCode`,那么应该写成`<if test="skuCode != null">` 如果是在注解中使用(如@SelectProvider等),确保在方法参数前使用`@Param("skuCode")`来指定参数名,这样在XML中就可以使用`skuCode`。 总结:这个问题的根本原因是MyBatis无法通过反射找到对应的getter方法,所以检查实体类的字段getter方法,以及XML中的属性引用,确保一致。 下面我们用一个简单的例子来说明: 实体类UserDto: ```java public class UserDto { private String dataTime; // 注意这里字段名是dataTime // 错误:没有提供getter方法 // 正确:应该提供 public String getDataTime() { return dataTime; } } ``` 在XML中: ```xml <select id="selectUser" parameterType="UserDto" resultType="UserDto"> SELECT * FROM user <where> <if test="dataTime != null"> <!-- 这里会调用getDataTime()方法 --> and data_time = #{dataTime} </if> </where> </select> ``` 如果没有`getDataTime`方法,就会报错:There is no getter for property named 'dataTime' in 'class com.dto.UserDto' 因此,解决方法就是为UserDto类添加`getDataTime`方法。 如果使用Lombok,只需要在类上加上`@Data`注解即可。 如果问题仍然存在,请检查编译后的class文件中是否确实生成了getter方法(有时候IDE缓存问题可能导致看不到最新的编译结果,可以尝试清理并重新编译)。 最后,如果实体类中确实没有这个属性,那么可能是XML中的条件写错了,需要修改XML文件中的属性名为正确的属性名。 根据引用[3][4],有时重新生成实体类Mapper文件(如果使用代码生成工具)可以解决问题,但前提是数据库字段实体类映射正确。 因此,针对这个错误的解决,核心就是:检查属性名getter方法,确保一致。</think>### 解决 MyBatis "There is no getter for property named 'xxx'" 错误 这个错误表示 MyBatis 在访问 Java 实体类属性时找不到对应的 getter 方法。以下是系统化的解决方案: #### 1. **检查实体类属性 getter 方法** - 确保实体类中存在与 XML 引用的属性名完全一致的字段 - 确认字段有符合 JavaBean 规范的 getter 方法(`getXxx()` 或布尔类型的 `isXxx()`) - 示例: ```java // 错误示例:缺少 getSkuCode() 方法 public class HsCode { private String SKUCODE; // 大写字段名 } // 正确示例 public class HsCode { private String skuCode; // 推荐驼峰命名 public String getSkuCode() { // 标准getter return this.skuCode; } } ``` #### 2. **解决命名不一致问题** - **大小写敏感**:MyBatis 严格匹配属性名大小写 ```xml <!-- 错误:XML 使用大写的 SKUCODE --> <if test="SKUCODE != null"> <!-- 应改为 skuCode --> ``` - **驼峰命名转换**: - 在 `mybatis-config.xml` 启用驼峰转换: ```xml <settings> <setting name="mapUnderscoreToCamelCase" value="true"/> </settings> ``` #### 3. **检查 MyBatis 映射文件** - 动态 SQL 中的属性名必须与实体类 getter 方法名匹配: ```xml <!-- 正确示例 --> <select id="selectBySku" parameterType="HsCode"> SELECT * FROM table <where> <if test="skuCode != null"> <!-- 对应 getSkuCode() --> sku_code = #{skuCode} </if> </where> </select> ``` #### 4. **验证 Lombok 生成(如使用)** - 确保 Lombok 注解正确应用: ```java @Data // 自动生成 getter/setter public class UserDto { private LocalDateTime dataTime; // 自动生成 getDataTime() } ``` - 验证编译后的 `.class` 文件是否包含 getter 方法 #### 5. **参数绑定问题** - 使用 `@Param` 注解明确指定参数名: ```java // 接口方法 List<HsCode> selectBySku(@Param("skuCode") String code); ``` ```xml <!-- XML 使用 --> <if test="skuCode != null"> <!-- 不再依赖参数位置 --> ``` #### 6. **重新生成实体类(极端情况)** 当字段被意外修改时(如引用[4]所述): - 重新运行 MyBatis 代码生成器 - **禁止手动修改生成的实体类**,应通过配置文件调整 > **关键检查点**: > 1. 编译后的 `.class` 文件是否包含目标 getter 方法 > 2. MyBatis 日志中执行的 SQL 参数绑定过程 > 3. 使用 `obj.getClass().getDeclaredMethods()` 动态验证方法存在性 ### 典型错误场景分析 | 场景 | 错误示例 | 解决方案 | |------|----------|----------| | 大小写不匹配 | XML: `test="SKUCODE"`<br>Getter: `getSkuCode()` | 统一为小写驼峰命名 | | Lombok 未生效 | 编译后缺少 getter | 检查 IDE Lombok 插件 | | 接口参数缺失 | 方法参数无 `@Param` | 添加 `@Param("xxx")` | | 布尔类型错误 | 字段 `isActive`<br>Getter: `getIsActive()` | 改为 `isActive()` | [^1]: 属性名大小写敏感问题 [^2]: 动态 SQL 中的属性引用错误 [^3]: Lombok 生成 getter 的验证需求 [^4]: 重新生成实体类的解决方案
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值