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

Spring项目登录查询抛出MyRowMapper不可序列化异常如何解决

报错根因
  • 从异常堆栈最底层溯源,抛出NotSerializableException的对象是com.example.dao.UserDao$MyRowMapper,也就是自定义的行映射类,这个类本身既不该作为SQL查询入参传给数据库,也没有实现序列化接口。
  • 触发错误的直接原因是UserDao.login方法在调用JdbcTemplate查询时参数顺序完全错误:
    • 调用queryForList方法时,你将MyRowMapper实例放到了方法的可变参数位置,而queryForList(String sql, Object... args)重载会把第二个参数开始的所有入参,全部当作SQL占位符?的绑定值处理
    • 你的SQL只有2个占位符,但因为多传了MyRowMapper,实际会传入3个绑定参数;MySQL驱动收到非基础类型的MyRowMapper参数时,默认会尝试将对象序列化后传入数据库,而MyRowMapper未实现Serializable接口,因此直接抛出异常
  • 对应错误代码大概率是类似下面的写法:
    // 错误示例:MyRowMapper被当成SQL绑定参数传入
    jdbcTemplate.queryForList(
        "select * from user where email=? and pass=?",
        new MyRowMapper(), // 错误:这个位置应该传查询入参[email, password]
        email,
        password
    );
    
可落地修复方案
  • 严格匹配JdbcTemplate方法的签名传参,修正参数顺序:
    • 如果你不需要自定义RowMapper、只需要返回List<Map<String, Object>>格式的查询结果,直接用queryForList传绑定参数即可:
      // 正确写法:SQL后直接跟和占位符一一对应的入参
      List<Map<String, Object>> userList = jdbcTemplate.queryForList(
          "select * from user where email=? and pass=?",
          email, password
      );
      
    • 如果你需要用MyRowMapper做行映射,不要用queryForList,改用query方法并按正确顺序传参:
      // 正确写法:SQL → 绑定参数数组 → RowMapper
      List<User> userList = jdbcTemplate.query(
          "select * from user where email=? and pass=?",
          new Object[]{email, password},
          new MyRowMapper()
      );
      
      // 或者使用可变参数重载版本(注意顺序:SQL → RowMapper → 绑定参数)
      List<User> userList = jdbcTemplate.query(
          "select * from user where email=? and pass=?",
          new MyRowMapper(),
          email, password
      );
      
  • 防御性优化:如果MyRowMapper是定义在UserDao内部的非静态内部类,建议改为static修饰的静态内部类,避免持有外部类引用带来的不必要开销;如果后续有序列化需求,再让其实现Serializable接口并指定序列化ID。
  • 快速排查技巧:后续遇到类似SQL绑定参数错误的异常时,可在JdbcTemplate执行前打断点,查看传入给ArgumentPreparedStatementSetter的参数列表,即可直接定位哪个非预期对象被误传为SQL入参。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.25 01:06:08