当前位置:  开发笔记 > 编程语言 > 正文

ResultSetImpl.checkColumnBounds或ResultSetImpl.getStringInternal中偶尔出现NullPointerException

如何解决《ResultSetImpl.checkColumnBounds或ResultSetImpl.getStringInternal中偶尔出现NullPointerException》经验,为你挑选了0个好方法。

首先,请不要关闭它作为什么NullPointerException以及如何解决它的副本.我知道是什么NullPointerException,我知道如何在我自己的代码中解决它,但不是当它被mysql-connector-java-5.1.36-bin.jar抛出时,我无法控制.

我们在mySQL数据库上运行公共数据库查询时遇到异常,该查询在大多数情况下都有效.我们在部署新版本后开始看到此异常,但发生它的查询在很长一段时间内没有发生变化.

以下是查询的外观(通过一些必要的简化).我用之前和之后执行的一些逻辑包围了它.实际的代码不是全部都在一个单独的方法中,但我把它放在一个块中,以便更容易理解.

Connection conn = ... // the connection is open
...
for (String someID : someIDs) {
    SomeClass sc = null;
    PreparedStatement
        stmt = conn.prepareStatement ("SELECT A, B, C, D, E, F, G, H FROM T WHERE A = ?");
    stmt.setString (1, "someID");
    ResultSet res = stmt.executeQuery ();
    if (res.next ()) {
        sc = new SomeClass ();
        sc.setA (res.getString (1));
        sc.setB (res.getString (2));
        sc.setC (res.getString (3));
        sc.setD (res.getString (4));
        sc.setE (res.getString (5));
        sc.setF (res.getInt (6));
        sc.setG (res.getString (7));
        sc.setH (res.getByte (8)); // the exception is thrown here
    }
    stmt.close ();
    conn.commit ();
    if (sc != null) {
        // do some processing that involves loading other records from the
        // DB using the same connection
    }
}
conn.close();

res.getByte(8)NullPointerException使用以下调用堆栈导致a :

com.mysql.jdbc.ResultSetImpl.checkColumnBounds(ResultSetImpl.java:763)com.mysql.jdbc.ResultSetImpl.getStringInternal(ResultSetImpl.java:5251)com.mysql.jdbc.ResultSetImpl.getString(ResultSetImpl.java:5173)com. mysql.jdbc.ResultSetImpl.getByte(ResultSetImpl.java:1650)org.apache.tomcat.dbcp.dbcp2.DelegatingResultSet.getByte(DelegatingResultSet.java:206)org.apache.tomcat.dbcp.dbcp2.DelegatingResultSet.getByte(DelegatingResultSet. Java的:206)

我搜索了相关mysql-connector版本的源代码,发现了这个(取自这里):

756 protected final void checkColumnBounds(int columnIndex) throws SQLException {
757     synchronized (checkClosed().getConnectionMutex()) {    
758         if ((columnIndex < 1)) {    
759             throw SQLError.createSQLException(    
760                   Messages.getString("ResultSet.Column_Index_out_of_range_low",    
761                   new Object[] { Integer.valueOf(columnIndex), Integer.valueOf(this.fields.length) }), SQLError.SQL_STATE_ILLEGAL_ARGUMENT,
762                   getExceptionInterceptor());   
763         } else if ((columnIndex > this.fields.length)) {    
764             throw SQLError.createSQLException(    
765                   Messages.getString("ResultSet.Column_Index_out_of_range_high",    
766                   new Object[] { Integer.valueOf(columnIndex), Integer.valueOf(this.fields.length) }), SQLError.SQL_STATE_ILLEGAL_ARGUMENT,   
767                   getExceptionInterceptor());
768         }
769
770         if (this.profileSql || this.useUsageAdvisor) {
771             this.columnUsed[columnIndex - 1] = true;
772         }
773     }
774 }

如您所见,此行发生异常:

} else if ((columnIndex > this.fields.length)) {   

这意味着this.fields不知怎的null.

我能找到的最接近的是这个问题,没有答案.

我怀疑问题不在我发布的查询中.Connection由于我们在同一个连接上运行的其他一些语句,实例可能出现了问题.我只能说,我们在执行它并从中读取数据后立即关闭每个语句ResultSet.

编辑(1/19/2017):

我无法在开发环境中重新创建错误.我认为可能是长时间使用相同连接时触发的一些mysql-connector错误.我限制上面的循环一次加载最多6个元素.另外,我们将mysql-connector版本升级到5.1.40.

我们仍然看到NullPointerExceptions ResultSetImpl,但这次是在不同的位置.

堆栈跟踪是:

com.mysql.jdbc.ResultSetImpl.getStringInternal(ResultSetImpl.java:5294)com.mysql.jdbc.ResultSetImpl.getString(ResultSetImpl.java:5151)org.apache.tomcat.dbcp.dbcp2.DelegatingResultSet.getString(DelegatingResultSet.java: 198)org.apache.tomcat.dbcp.dbcp2.DelegatingResultSet.getString(DelegatingResultSet.java:198)

这意味着这次由于我们的一个res.getString()调用而抛出了异常(我不知道哪一个).

我发现源使用mysql-connector-java的5.1.40-bin.jar 这里和相关的代码是:

5292            // Handles timezone conversion and zero-date behavior
5293
5294            if (checkDateTypes && !this.connection.getNoDatetimeStringSync()) {
5295                switch (metadata.getSQLType()) {

暗示this.connection是null.this.connection是一个类型的实例变量MySQLConnection,它在构造函数中被初始化,ResultSetImpl并且在public void realClose(boolean calledExplicitly)被调用时仅被设置为null (它被调用public void close(),根据源中的文档,在被调用时ResultSet.close()被调用).我们绝对不会ResultSet在阅读之前读取所有数据.

任何想法如何进行?

推荐阅读
yzh148448
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有