解决Mybatis出现报错Error querying database.Cause: java.lang.IndexOutOfBoundsException: Index 9 out of
作者:初心绘流年
错误现象
确认SQL没有任何问题,但是在执行时仍然出现以下报错,报错下标越界:IndexOutOfBoundsException: Index 9 out of bounds for length 9
18:02:19.449 [http-nio-8007-exec-10] DEBUG c.t.c.c.d.GyUserWithdrawDao.listWihdraw - ==> Preparing: SELECT gyw.*, ui.realname realname FROM `gy_user_withdraw` gyw inner join user_info ui on gyw.user_id = ui.userid LIMIT ?
18:02:19.450 [http-nio-8007-exec-10] DEBUG c.t.c.c.d.GyUserWithdrawDao.listWihdraw - ==> Parameters: 10(Integer)
18:02:19.466 [http-nio-8007-exec-10] ERROR c.t.c.exception.ExceptionHandlerAdvice - 运行异常
org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.PersistenceException:
### Error querying database. Cause: java.lang.IndexOutOfBoundsException: Index 9 out of bounds for length 9
### The error may exist in file [D:\CIMS\gyyh_2.3.3\cims_commons_db\target\classes\mybatis\mysql\GyUserWithdrawMapper.xml]
### The error may involve com.trusfort.cims.commons.dao.GyUserWithdrawDao.listWihdraw
### The error occurred while handling results
### SQL: SELECT gyw.*, ui.realname realname FROM `gy_user_withdraw` gyw inner join user_info ui on gyw.user_id = ui.userid LIMIT ?
### Cause: java.lang.IndexOutOfBoundsException: Index 9 out of bounds for length 9
at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:92)
at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:440)
at com.sun.proxy.$Proxy172.selectList(Unknown Source)
at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:223)
at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147)
at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80)
at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:144)
at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:85)
at com.sun.proxy.$Proxy369.listWihdraw(Unknown Source)
错误原因
很明显不是SQL的问题,从日志来看SQL明显没有问题,而且我们的Mapper.xml中配置也没有问题
<select id="listWihdraw" resultType="GyUserWithdraw"> SELECT gyw.*, ui.realname realname FROM `gy_user_withdraw` gyw inner join user_info ui on gyw.user_id = ui.userid </select>
那就只能从Mybatis执行SQL后查询结果到实体映射的角度出发来考虑了。
我们看一下我们的实体类源码
@Data @Builder(toBuilder = true) public class GyUserWithdraw implements Serializable { private String id; private String userId; private String employeenum; private String statusBefore; private String statusAfter; private String syncResult; private Date createTime; private Date updateTime; }
看着貌似是没什么毛病,但鉴于我们此处偷懒使用了Lombok的插件,还是仔细考虑回想一下
我们一般写数据库实体类的时候,只要有字段定义和对应的getter、setter方法就可以了
为何用了Lombok的@Data注解之后有问题了呢?
我们看一下编译后的实体类,用IDEA查看一下class反编译的结果
重点来了
我们会发现与原本不使用Lombok的实体类相比,该类只有一个全参数的构造方法,而原本我们手写实体类时只写了getter和setter方法,所以编译后会默认带一个无参构造。
而上述使用Lombok的@Builder
注解后,编译后实体有全参数的构造方法,那么编译器就不会再默认提供一个默认的无参构造。
所以问题可能就出现在这个无参构造方法缺失上,mybatis在将查询结果映射成实体时是通过无参构造获得一个实例,然后调用setter方法将值存入相应字段的。
解决方案
我们可以使用Lombok注解@NoArgsConstructor
和@AllArgsConstructor
,使编译器编译的时候提供出无参构造。
在原实体上增加两个注解即可,我们再重试就会发现SQL执行正常了。
@Data @Builder(toBuilder = true) @NoArgsConstructor @AllArgsConstructor
注意:
因为我们使用@Builder
注解,所以光添加一个@NoArgsConstructor
,程序会编译报错的,builder需要一个全参构造,所以我们还得加上@AllArgsConstructor
。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
您可能感兴趣的文章:
- MybatisPlus出现Error attempting to get column ‘xxx字段‘ from result set异常解决
- MyBatis异常java.sql.SQLSyntaxErrorException的问题解决
- Mybatis操作数据时出现:java.sql.SQLSyntaxErrorException: Unknown column 'XXX' in 'field list'的问题解决
- MybatisPlusException:Failed to process,Error SQL异常报错的解决办法
- Mybatis配置错误:java.lang.ExceptionInInitializerError
- MybatisPlus BaseMapper 中的方法全部 Invalid bound statement (not found Error处理)