最近遇到了一件极其诡异的Mybatis查询数组越界异常(java.sql.SQLException: java.lang.ArrayIndexOutOfBoundsException)的问题,排查了一天,最终解决了该问题。
一、问题描述
Mapper代码
@Mapper
public interface ISmeBidDailyMapper extends BaseMapper<SmeBidDaily> {
List<SmeBidDaily> listQuery(@Param("lastMaxId") Long lastMaxId,
@Param("maxDataTime") String maxDataTime,
@Param("pageSize") Integer pageSize);
}
对应的XMl代码
<select id="listQuery" resultType="com.cosmoplat.gfqd.gxh.data.syn.bid.sme_bid_daily.entity.SmeBidDaily">
SELECT
*
FROM `sme_bid_daily`
WHERE id > #{lastMaxId}
AND `created_at` <= #{maxDataTime}
ORDER BY id ASC
limit #{pageSize}
</select>
以上代码运行的时候,会抛出两种错误:
第一种错误:
JDBC Connection [HikariProxyConnection@1915066553 wrapping com.mysql.cj.jdbc.ConnectionImpl@2c9a855f] will not be managed by Spring
==> Preparing: SELECT id, mid, attachment_flag, bid_type, bid_info_type, bid_project_title, bid_num, bid_location, bid_province, bid_project_category, budgetary, bid_ent, proxy_ent, bid_win, contact, contact_type, contact_person, contact_has_more, bid_pubtime, updated, region_code, title_key_word, text_key_word, product_word, ent_nic, match_text, bid_text, state, created_at, original_url FROM `sme_bid_daily` WHERE id > ? AND `created_at` <= ? ORDER BY id ASC limit ?
==> Parameters: 1604549(Long), 2026-04-30T00:00(LocalDateTime), 10000(Integer)
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@49af67c7]
2026-04-01 15:23:37 [Thread-22] ERROR c.c.g.g.d.s.b.s.j.SynSmeBidDailyToEs -
org.springframework.dao.TransientDataAccessResourceException:
### Error querying database. Cause: java.sql.SQLException: java.lang.ArrayIndexOutOfBoundsException: 31
### The error may exist in class path resource [mappers/ISmeBidDailyMapper.xml]
### The error may involve defaultParameterMap
### The error occurred while setting parameters
### SQL: SELECT id, mid, attachment_flag, bid_type, bid_info_type, bid_project_title, bid_num, bid_location, bid_province, bid_project_category, budgetary, bid_ent, proxy_ent, bid_win, contact, contact_type, contact_person, contact_has_more, bid_pubtime, updated, region_code, title_key_word, text_key_word, product_word, ent_nic, match_text, bid_text, state, created_at, original_url FROM `sme_bid_daily` WHERE id > ? AND `created_at` <= ? ORDER BY id ASC limit ?
### Cause: java.sql.SQLException: java.lang.ArrayIndexOutOfBoundsException: 31
; java.lang.ArrayIndexOutOfBoundsException: 31; nested exception is java.sql.SQLException: java.lang.ArrayIndexOutOfBoundsException: 31
第二种错误:
2026-04-01 15:23:43 [Thread-22] ERROR c.c.g.g.d.s.b.s.j.SynSmeBidDailyToEs -
org.springframework.dao.TransientDataAccessResourceException:
### Error querying database. Cause: java.sql.SQLException: java.lang.ArrayIndexOutOfBoundsException
### The error may exist in class path resource [mappers/ISmeBidDailyMapper.xml]
### The error may involve defaultParameterMap
### The error occurred while setting parameters
### SQL: SELECT id, mid, attachment_flag, bid_type, bid_info_type, bid_project_title, bid_num, bid_location, bid_province, bid_project_category, budgetary, bid_ent, proxy_ent, bid_win, contact, contact_type, contact_person, contact_has_more, bid_pubtime, updated, region_code, title_key_word, text_key_word, product_word, ent_nic, match_text, bid_text, state, created_at, original_url FROM `sme_bid_daily` WHERE id > ? AND `created_at` <= ? ORDER BY id ASC limit ?
### Cause: java.sql.SQLException: java.lang.ArrayIndexOutOfBoundsException
; java.lang.ArrayIndexOutOfBoundsException; nested exception is java.sql.SQLException: java.lang.ArrayIndexOutOfBoundsException
......
Caused by: java.lang.ArrayIndexOutOfBoundsException: null
二、规律总结
一开始怀疑本地的jdk和k3s集群运行的jre版本不同,我本地的jdk是oracle jdk,在k3s集群容器环境下运行的是openjdk-internel版本,我将k3s集群容器中的jre和我本地的jdk统统都换成了jdk8u482-b08版本,但是问题依旧,所以排除了和运行的jdk版本的关系;
又怀疑jenkins打包是否发生了什么问题,所以我将容器中的jar包取出来在本地运行,结果本地运行一点问题没有,无法复现;
至此,我本地的jdk和jar包都和线上保持一致了,but我本地运行N次还是没有复现问题,线上请求一两次就会报错,甚至连续请求连续报错。
我都开始怀疑人生了,干了这么多年的后端开发,第一次遇到这种诡异的问题。
后来怀疑是不是k3s集群的问题,我将同样的镜像部署到k8s集群中运行,结果k8s集群中运行是好的,没法复现,这说明是k3s集群有问题?
怀疑k3s网络有问题,听说MTU设置的不对也会出现这个问题,但是为什么别的服务没有问题,就单单这个服务出了问题?接着又怀疑jdbc链接中设置的不对,禁止了Mysql服务端预编译,仍然没有解决问题。
经过反复测试,最终发现了如下规律:
1、在本地环境下无法复现
2、在k3s集群中稳定复现,通常调用两三次就能出现上述异常
3、在k8s集群中无法复现
4、在linux环境非容器环境无法复现
5、和Mysql的JDBC服务端预编译配置无关
通过保持单一变量原则的测试,唯一有可能存在问题的是k3s的运行环境有问题,否则说不通为什么相同的镜像在k8s集群中运行没有问题。
最后没法子了,只能远程debug,远程debug也行不通,因为这个问题时好时坏,不能每次都重现,找到了抛出异常的地方,但是真正执行逻辑的方法已经在方法栈中弹出,堆栈信息已经没有了,断点都不知道打在什么地方。
问题陷入了死循环,似乎根本无解,至此我唯一能想到的解决方案就是不再在容器中运行,把jar包拿出来直接放到宿主机使用java -jar 启动。
三、解决问题
要不说还得是大模型,大模型随口提了一句检查下mysql驱动是否有问题,最后实在没招的我,把mysql驱动从
<dependency>
<artifactId>mysql-connector-java</artifactId>
<groupId>mysql</groupId>
<version>8.0.31</version>
</dependency>
替换成了
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>8.0.33</version>
</dependency>
问题竟然解决了。。。问题解决了,解决了问题的我内心没有丝毫波澜,只有满肚子的疑问。
1、如果是驱动的问题,为什么在本地无法复现问题,在k8s集群中没有复现问题,只有在k3s集群中出现了数组越界异常的问题。
2、为什么在k3s集群中有时候有问题,有时候没问题,这个还能有偶发性情况吗。
END.
注意:本文归作者所有,未经作者允许,不得转载