ShardingSphere导致的NPE

devtools/2024/9/24 10:55:46/

1. 项目背景

工程内使用shardingsphere支持分库分表,上层使用的MybatisPlus,有一张表的操作总是报NullPointException。

2. 异常堆栈

### SQL: INSERT INTO t_tg_message  ( update_id, from_id, from_user_name, chat_id, type, data, text, create_time, deleted )  VALUES  ( ?, ?, ?, ?, ?, ?, ?, ?, ? )
### Cause: java.lang.NullPointerExceptionat org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:92) ~[mybatis-spring-2.0.5.jar!/:2.0.5]at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:440) ~[mybatis-spring-2.0.5.jar!/:2.0.5]at com.sun.proxy.$Proxy141.insert(Unknown Source) ~[?:?]at org.mybatis.spring.SqlSessionTemplate.insert(SqlSessionTemplate.java:271) ~[mybatis-spring-2.0.5.jar!/:2.0.5]at com.baomidou.mybatisplus.core.override.MybatisMapperMethod.execute(MybatisMapperMethod.java:60) ~[mybatis-plus-core-3.4.0.jar!/:3.4.0]at com.baomidou.mybatisplus.core.override.MybatisMapperProxy$PlainMethodInvoker.invoke(MybatisMapperProxy.java:148) ~[mybatis-plus-core-3.4.0.jar!/:3.4.0]at com.baomidou.mybatisplus.core.override.MybatisMapperProxy.invoke(MybatisMapperProxy.java:89) ~[mybatis-plus-core-3.4.0.jar!/:3.4.0]at com.sun.proxy.$Proxy298.insert(Unknown Source) ~[?:?]at com.keyniu.user.web.tg.interceptors.impl.RecordInterceptor.appendMessage(RecordInterceptor.java:83) ~[classes!/:?]at com.keyniu.user.web.tg.interceptors.impl.RecordInterceptor.process(RecordInterceptor.java:40) ~[classes!/:?]at com.keyniu.user.web.tg.interceptors.Interceptor.intercept(Interceptor.java:13) ~[classes!/:?]at com.keyniu.user.web.tg.interceptors.InterceptorChain.process(InterceptorChain.java:37) ~[classes!/:?]at com.keyniu.user.web.tg.tgBot.onUpdateReceived(tgBot.java:70) ~[classes!/:?]at java.util.ArrayList.forEach(ArrayList.java:1541) ~[?:?]at org.tg.tgbots.meta.generics.LongPollingBot.onUpdatesReceived(LongPollingBot.java:27) ~[tgbots-meta-6.0.1.jar!/:?]at org.tg.tgbots.updatesreceivers.DefaultBotSession$HandlerThread.run(DefaultBotSession.java:317) ~[tgbots-6.0.1.jar!/:?]
Caused by: org.apache.ibatis.exceptions.PersistenceException:
### Error updating database.  Cause: java.lang.NullPointerException
### The error may exist in com/keyniu/out/mapper/TgMessageMapper.java (best guess)
### The error may involve com.keyniu.user.persist.thirdparty.mapper.TgMessageMapper.insert-Inline
### The error occurred while setting parameters
### SQL: INSERT INTO t_tg_message  ( update_id, from_id, from_user_name, chat_id, type, data, text, create_time, deleted )  VALUES  ( ?, ?, ?, ?, ?, ?, ?, ?, ? )
### Cause: java.lang.NullPointerExceptionat org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30) ~[mybatis-3.5.5.jar!/:3.5.5]at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:199) ~[mybatis-3.5.5.jar!/:3.5.5]at org.apache.ibatis.session.defaults.DefaultSqlSession.insert(DefaultSqlSession.java:184) ~[mybatis-3.5.5.jar!/:3.5.5]at jdk.internal.reflect.GeneratedMethodAccessor312.invoke(Unknown Source) ~[?:?]at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]at java.lang.reflect.Method.invoke(Method.java:566) ~[?:?]at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:426) ~[mybatis-spring-2.0.5.jar!/:2.0.5]... 14 more
Caused by: java.lang.NullPointerExceptionat org.antlr.v4.runtime.tree.AbstractParseTreeVisitor.visit(AbstractParseTreeVisitor.java:18) ~[antlr4-runtime-4.7.2.jar!/:4.7.2]at org.apache.shardingsphere.sql.parser.mysql.visitor.impl.MySQLDMLVisitor.visitInsert(MySQLDMLVisitor.java:147) ~[shardingsphere-sql-parser-mysql-4.1.1.jar!/:4.1.1]at org.apache.shardingsphere.sql.parser.mysql.visitor.impl.MySQLDMLVisitor.visitInsert(MySQLDMLVisitor.java:127) ~[shardingsphere-sql-parser-mysql-4.1.1.jar!/:4.1.1]at org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser$InsertContext.accept(MySQLStatementParser.java:1090) ~[shardingsphere-sql-parser-mysql-4.1.1.jar!/:4.1.1]at org.antlr.v4.runtime.tree.AbstractParseTreeVisitor.visit(AbstractParseTreeVisitor.java:18) ~[antlr4-runtime-4.7.2.jar!/:4.7.2]at org.apache.shardingsphere.sql.parser.SQLParserEngine.parse0(SQLParserEngine.java:80) ~[shardingsphere-sql-parser-engine-4.1.1.jar!/:4.1.1]at org.apache.shardingsphere.sql.parser.SQLParserEngine.parse(SQLParserEngine.java:61) ~[shardingsphere-sql-parser-engine-4.1.1.jar!/:4.1.1]at org.apache.shardingsphere.underlying.route.DataNodeRouter.createRouteContext(DataNodeRouter.java:97) ~[shardingsphere-route-4.1.1.jar!/:4.1.1]at org.apache.shardingsphere.underlying.route.DataNodeRouter.executeRoute(DataNodeRouter.java:89) ~[shardingsphere-route-4.1.1.jar!/:4.1.1]at org.apache.shardingsphere.underlying.route.DataNodeRouter.route(DataNodeRouter.java:76) ~[shardingsphere-route-4.1.1.jar!/:4.1.1]at org.apache.shardingsphere.underlying.pluggble.prepare.PreparedQueryPrepareEngine.route(PreparedQueryPrepareEngine.java:54) ~[shardingsphere-pluggable-4.1.1.jar!/:4.1.1]at org.apache.shardingsphere.underlying.pluggble.prepare.BasePrepareEngine.executeRoute(BasePrepareEngine.java:96) ~[shardingsphere-pluggable-4.1.1.jar!/:4.1.1]at org.apache.shardingsphere.underlying.pluggble.prepare.BasePrepareEngine.prepare(BasePrepareEngine.java:83) ~[shardingsphere-pluggable-4.1.1.jar!/:4.1.1]at org.apache.shardingsphere.shardingjdbc.jdbc.core.statement.ShardingPreparedStatement.prepare(ShardingPreparedStatement.java:183) ~[sharding-jdbc-core-4.1.1.jar!/:4.1.1]at org.apache.shardingsphere.shardingjdbc.jdbc.core.statement.ShardingPreparedStatement.execute(ShardingPreparedStatement.java:143) ~[sharding-jdbc-core-4.1.1.jar!/:4.1.1]at jdk.internal.reflect.GeneratedMethodAccessor232.invoke(Unknown Source) ~[?:?]at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]

3. 问题定位

一开始是怀疑某个参数字段为空了,反复检查后确定参数都正确设置。表对应的实体类如下:

@Data
@Builder
@TableName("t_tg_message")
public class TgMessageEntity {@TableId(type = IdType.AUTO)private Long id;private Integer updateId;private Long fromId;private String fromUserName;private Long chatId;private String type;private String data;private String text;private Date createTime;private Integer deleted;
}

打开MybatisPlus源码抛异常的位置, DEBUG后确定executor、ms、parameter都不是空,才开始关注到root cause,其实是shardingsphere抛出的
在这里插入图片描述

看异常堆栈显然是SQL解析报错了,SQL都是生成的,按理应该也没有错,这个时候才关注到字段名可能是数据库关键字,导致解析失败,报了一个莫名其妙的NPE。

Caused by: java.lang.NullPointerExceptionat org.antlr.v4.runtime.tree.AbstractParseTreeVisitor.visit(AbstractParseTreeVisitor.java:18) ~[antlr4-runtime-4.7.2.jar!/:4.7.2]at org.apache.shardingsphere.sql.parser.mysql.visitor.impl.MySQLDMLVisitor.visitInsert(MySQLDMLVisitor.java:147) ~[shardingsphere-sql-parser-mysql-4.1.1.jar!/:4.1.1]at org.apache.shardingsphere.sql.parser.mysql.visitor.impl.MySQLDMLVisitor.visitInsert(MySQLDMLVisitor.java:127) ~[shardingsphere-sql-parser-mysql-4.1.1.jar!/:4.1.1]at org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser$InsertContext.accept(MySQLStatementParser.java:1090) ~[shardingsphere-sql-parser-mysql-4.1.1.jar!/:4.1.1]

4. 经验教训

  1. shardingsphere之类的,要注意是否为关键字,否则有莫名奇妙的问题
  2. 代码错误可读性和精准,如果一开始报错就是SQL内有关键字,或者MybatisPlus生成SQL的时候转义SQL,体验会好很多

http://www.ppmy.cn/devtools/98752.html

相关文章

项目问题 | CentOS 7停止维护导致yum失效的解决办法

目录 centos停止维护意味着yum相关源伴随失效。 报错: 解决方案:将图中四个文件替换掉/etc/yum.repos.d/目录下同名文件 资源提交在博客头部,博客结尾也提供文件源码内容 CentOS-Base.repo CentOS-SCLo-scl.repo CentOS-SCLo-scl-rh.rep…

零基础STM32单片机编程入门(三十九) 多传感器模块之NFC刷卡开门实战源码

文章目录 一.概要二.实验原理三.实验控制流程四.STM32单片机刷卡开门实验(RC522刷卡模块SG90舵机)五.CubeMX工程源代码下载六.实验效果七.小结 一.概要 NFC技术作为一种近距离无线通信技术,具有安全、便捷、高效的特点。随着智能手机的普及和移动支付的发展&#x…

k8s学习(三十八) 使用OpenTelemetry+jaeger实现链路追踪

文章目录 前言一、安装jaeger二、安装cert-manager三、安装OpenTelemetry Operator四、配置 OpenTelemetry Collector五、配置 Instrumentation六、编写java示例程序并测试调用链跟踪 前言 OpenTelemetry 可以用于从应用程序收集数据。它是一组工具、API 和 SDK 集合&#xff…

【CSP:202305-2】矩阵运算(Java)

题目链接 202305-2 矩阵运算 题目描述 求解思路 调整矩阵运算的顺序:根据矩阵运算符合结合律这一特点,对运算式的顺序进行调整。根据题目给出的数据范围,我们可以先将 K T ( d ∗ n ) K^T(d*n) KT(d∗n) 矩阵和 V ( n ∗ d ) V(n*d) V(n…

MySQL表涉及规范

MySQL表设计规范是为了确保数据库表结构的合理性、可读性和可维护性。以下是一些建议和规范: 1.使用InnoDB存储引擎:InnoDB存储引擎提供了事务支持、行级锁定和外键约束,有助于提高数据的完整性和性能。 2.表名和字段名命名规范&#xff1a…

苹果手机mov转mp4:一键转换,轻松享受!

视频凭借其直观生动的形式,已经深深融入我们的日常生活之中,成为我们记录生活、分享情感、学习娱乐的重要媒介。作为市场上最受欢迎的智能手机品牌之一,苹果手机以其卓越的拍摄性能,为用户捕捉了无数精彩瞬间,而其拍摄…

ACCESS 工具注入实战 凡诺靶场

简介 Access数据库注入攻击是一种常见的网络安全,通过注入SQL代码来获取未授权的数据访问权限。这种攻击利用了应用程序与数据库之间的交互漏洞,攻击者通过输入特定的SQL代码片段来操纵数据库查询,从而绕过应用程序的安全机制,获取…

haproxy编译安装

一、haproxy简介 HAProxy是一个使用C语言编写的自由及开放源代码软件,其提供高可用性、负载均衡,以及基于TCP和HTTP的应用程序代理。 HAProxy特别适用于那些负载特大的web站点,这些站点通常又需要会话保持或七层处理。HAProxy运行在当前的硬…