前言
具体的异常信息如下:
Error attempting to get column 'open_id' from result set. Cause: java.lang.NumberFormatException: For input string: "oqmJX5ZPU1KOv-YDt30GNAN-Zefk"
乍一看下其实就是无法把open_id字符串类型转为数字类型进行赋值,但是如果没有碰到这个问题可能一时半会还找不到问题的所在,原因在下面细说
代码
@Data
@TableName(value = "login_user")
@ApiModel(value="LoginUser对象", description="玩家账号表")
public class LoginUser implements Serializable {private static final long serialVersionUID = 1L;@TableId(value = "id", type= IdType.AUTO)@ApiModelProperty(value = "主键ID-自增")private Long id;@ApiModelProperty(value = "创建时间")private Long createTime;@ApiModelProperty(value = "平台")private String platform;@ApiModelProperty(value = "玩家account")private String openId;@ApiModelProperty(value = "渠道")private String channel;@ApiModelProperty(value = "玩家分区id")private Long serverId;@ApiModelProperty(value = "玩家pwd")private String pwd;@ApiModelProperty(value = "内部服务器主键id")private Long gameServerId;public LoginUser(String openId, String platform, String channel, Long serverId) {this.openId = openId;this.platform = platform;this.channel = channel;this.serverId = serverId;}
}
CREATE TABLE `login_user` (`id` bigint(20) NOT NULL COMMENT 'userID',`open_id` varchar(64) NOT NULL DEFAULT '' COMMENT '玩家account',`platform` varchar(64) NOT NULL DEFAULT '' COMMENT '平台',`channel` varchar(255) DEFAULT NULL COMMENT '渠道',`server_id` bigint(20) NOT NULL DEFAULT '0' COMMENT '玩家分区id',`game_server_id` bigint(20) DEFAULT NULL COMMENT '关联的服务器主键id',`create_time` bigint(20) NOT NULL DEFAULT '0' COMMENT '创号时间',`account` varchar(64) NOT NULL DEFAULT '' COMMENT '玩家account',`pwd` varchar(64) NOT NULL DEFAULT '' COMMENT '玩家pwd',PRIMARY KEY (`id`),KEY `idx_open_id` (`open_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='玩家账号表';
控制器
@GetMapping("/test") public LoginUser test(@RequestParam("id") Long id) {LoginUser byId = loginUserService.getById(id);return byId; }
就是通过id获取对象,注:这里需要一定的Java基础,这部分内容不在本篇文章讨论以内
如图所示,如果去访问这个接口会报以下的错
Error attempting to get column 'open_id' from result set. Cause: java.lang.NumberFormatException: For input string: "oqmJX5ZPU1KOv-YDt30GNAN-Zefk"
但是你可以很清楚的看到openId的定义为字符串,数据库的字段定义为varchar,类型是能匹配上的
问题解决
方法1-治标不治本
把 @ApiModelProperty(value = "创建时间")
private Long createTime;字段放到了id前面,再访问就正常了,这种方式虽然可以解决,但是指不定又出现其他问题,所以必须从根源进行问题解决
方法2-根源问题
如果要找到根源问题只能去看源码流程,看看到底是哪一步出错了,由于不知道具体问题出现在哪里,那就只能debug一步步去看哪里出错,然后去看到具体的原因,这部分需要一定的源码阅读能力,这里也主要是贴上观看的大概流程,以及最核心的问题所在稍微描述一下,整体的流程走向一篇文章肯定是说不完的
一些源码的截图
问题其实就是在handleResultSet方法里,可以看到我还打着断点
接着又是一顿追踪
最终定位到问题位置如下
描述:就是因为找到了其他的构造器,导致第4个参数是要整形,但是open_id是字符串,无法转换过来引起了报错,可以再看看LoginUser的定义,是不是这样的,只放核心的
@Data
@TableName(value = "login_user")
@ApiModel(value="LoginUser对象", description="玩家账号表")
public class LoginUser implements Serializable {public LoginUser(String openId, String platform, String channel, Long serverId) {this.openId = openId;this.platform = platform;this.channel = channel;this.serverId = serverId;}
}等于LoginUser只有一个构造器,我们需要为LoginUser添加一个无参的构造器
加上以后就正常了
总结
问题的本质就是因为少了无参构造器引起的,有参那个第四个参数刚好是数字类型的,openId为第四个肯定是设置不进去的
虽然问题并不复杂,但是下次如果看到类型的错误就多了一个思考的方向,也算是一个小经验了