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

Mybatis结果集自动映射文档查询及字段映射异常求助

MyBatis 结果集映射异常:null字段被错误赋值

我尝试查找MyBatis将ResultSet自动映射为对象的官方文档,但未找到相关细节,仅在社区讨论中发现过相关问题。我原本对MyBatis映射逻辑的理解是:

  • 优先查找无参构造器,通过反射直接访问字段赋值,无需依赖setter方法
  • 如果没有无参构造器,则使用多参构造器,按构造器参数声明顺序完成映射(构造器自动映射)

但这个解释无法解决我遇到的实际问题:使用@Data注解的MyUserDTO通过MyBatis Mapper映射时,数据库查询结果中address字段为null,但最终映射后的对象里,address字段却被注入了age字段的值。


代码示例

DTO类

@Data
class MyUserDTO {
    private Long id;
    private String name;
    private Integer age;
    private String address;
}

Mapper接口

@Mapper
interface UserMapper {
    @Select("SELECT * FROM user_table WHERE id = #{id}")
    MyUserDTO findByUserId(@Param("id") Long id);
}

数据库查询及结果

执行查询语句:SELECT * FROM user_table WHERE id = 1;
返回结果:

id | name | age | address
-------------------------
1  | jin  | 20  | null

调用findByUserId(1)后,userDTO.getAddress()返回"20"而非预期的null。


环境信息

  • Spring Boot 2.7.8
  • MyBatis 3.5.11(已配置map-underscore-to-camel-case: true)
  • SQLite 3
  • AdoptOpenJDK 11.0.11
  • macOS Ventura v13.2.1

问题原因分析

这个问题的核心是Lombok的@Data注解生成的构造器与MyBatis构造器自动映射逻辑冲突。

虽然@Data注解默认会生成无参构造器,但部分场景下,Lombok字节码生成的细节会导致MyBatis误判为需要使用构造器自动映射,而非直接访问字段赋值。再加上SQLite JDBC驱动返回ResultSet的列顺序可能与DTO字段声明顺序不一致,MyBatis在构造器映射时按参数位置而非名称匹配,最终导致age的值被错误赋值给address字段。

另外,MyBatis的自动映射逻辑会优先使用构造器(如果它认为可以用的话),而非直接字段访问,这进一步触发了顺序匹配的错误。


解决方案

  1. 显式添加无参构造器
    在MyUserDTO上添加@NoArgsConstructor注解,明确告诉MyBatis优先使用无参构造器+字段直接赋值:

    @Data
    @NoArgsConstructor
    class MyUserDTO {
        private Long id;
        private String name;
        private Integer age;
        private String address;
    }
    
  2. 关闭构造器自动映射
    在MyBatis配置中强制禁用构造器映射,确保MyBatis始终使用字段直接访问:

    mybatis:
      configuration:
        use-constructor-mappings: false
    
  3. 显式指定查询列名
    避免使用SELECT *,明确写出查询列并保持与DTO字段顺序一致,同时避免不必要的字段:

    @Select("SELECT id, name, age, address FROM user_table WHERE id = #{id}")
    MyUserDTO findByUserId(@Param("id") Long id);
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 16:07:41