java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > 解决Mybatis出现报错Error querying database.Cause: java.lang.IndexOutOfBoundsException: Index 9 out of

解决Mybatis出现报错Error querying database.Cause: java.lang.IndexOutOfBoundsException: Index 9 out of

作者:初心绘流年

这篇文章主要介绍了解决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

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文