绑定变量值为null的处理,引发NullPointerException

【 TiDB 使用环境】线上、测试、调研
【 TiDB 版本】TiDB 5.7.25
【遇到的问题】Spring-JDBC 5.2.21 + MySQL 驱动8.0.22在该版本上对绑定变量值为null的处理时抛出NullPointerException
【复现路径】SQL: select * from any_table where instr(:a, ‘a’); – :a绑定变量值为null
【问题现象及影响】使用了Spring-JDBC 5.2.21进行TiDB的数据访问,在org.springframework.jdbc.core.StatementCreatorUtils.setNull方法中,MysqlParameterMetadata元数据中获取ResultSetMetaData对象toString失败,导致了JDBC getParameterType call failed,抛出了NPE空指针异常。

又尝试了同样的组合,仅仅把TiDB替换成MySQL5.7,能正常返回结果。
实际是在sqlTypeToUse = ps.getParameterMetaData().getParameterType(paramIndex);这一步出现了NPE,早期的Spring-JDBC捕获了异常,升级到Spring-JDBC 5.2.21后此处仅捕获SQLException,故引发NPE错误。

if (tryGetParameterType) {
try {
sqlTypeToUse = ps.getParameterMetaData().getParameterType(paramIndex);
}
catch (Throwable ex) {
if (logger.isDebugEnabled()) {
logger.debug("JDBC 3.0 getParameterType call not supported - using fallback method instead: " + ex);
}
}
}

请问TiDB是否能支持正确的返回null的sql类型,即使是和MySQL一样的处理,返回一个sqlTypeToUse为null?

MySQL 驱动8.0.22 换成 MySQL 驱动 5 试试。

驱动回退不太行,太老了版本5,目前我们是改了spring.jdbc.getParameterType.ignore=true来跳过sqlTypeToUse这一步的设置,但还是希望TiDB看看有没有能兼容MySQL一样的处理方式。

您好,麻烦标注一下tidb的版本?
select tidb_version()\G

1 个赞

Release Version: v5.0.1
Edition: Community
Git Commit Hash: 1145e347d3469d8e89f88dce86f6926ca44b3cd8
Git Branch: heads/refs/tags/v5.0.1
UTC Build Time: 2021-04-23 05:51:17
GoVersion: go1.13
Race Enabled: false
TiKV Min Version: v3.0.0-60965b006877ca7234adaced7890d7b029ed1306
Check Table Before Drop: false

建议使用jdbc 5.1.49 ,官方的 jdbc 8 测试不是很全面。

tidb 6.1.2上碰到了同样的问题,驱动为 com.mysql:mysql-connector-j:8.0.31

java.lang.NullPointerException: null
	at com.mysql.cj.jdbc.result.ResultSetMetaData.getColumnType(ResultSetMetaData.java:190)

debug跟踪发现,ResultSetMetaData中拿到的Filed[]数组,长度和实际字段数目相等,但最后一个Filed为null,导致空指针异常。

使用mysql-connector-j-8.0.31.jar时会出现一些提示,你可以使用mysql-connector-java-5.1.47-bin.jar类似的JDBC驱动。在springboot的yml配置文件有com.mysql.cj.jdbc.Driver (MySQL8.0) 和 com.mysql.jdbc.Driver(MySQL5.7)的配置。

TiDB使用的数据库版本对应的是MySQL5.7

此话题已在最后回复的 60 天后被自动关闭。不再允许新回复。