最近项目整合了mybatis,做mybatis批量插入时报空指针异常,最后发现是没有设置超时时间,在此记录一下问题排查过程~
先附上解决代码(mybatis-config.xml):
<setting name="defaultStatementTimeout" value="20"/>
当调用提交commit()时出现空指针异常时,没有找到具体报错的类,只能根据堆栈信息一层层往下找
查询资料发现当使用commit时,会调用DefaultSqlSession.commit()
可以发现DefaultSqlSession.commit()中有个抛错
throw ExceptionFactory.wrapException("Error committing transaction. Cause: " + var6, var6);
其中错误信息(Error committing transaction. Cause)与我们遇到的抛错信息一致,在抛错行打断点,执行操作发现确实是这里抛出的错,那么大致判断就是DefaultSqlSession.commit()出现空指针异常;
继续往下找到BaseExecutor.commit();因为我们使用的是ExecutorType.BATCH,对应的执行器的类是BatchExecutor,所以找到BatchExecutor.doFlushStatements()
但是继续打断点,发现这个方法中的第一行和最后一行都执行了,而整个代码中第一层的try有finally,但是没有catch,大致判断出就是第一个try出现问题,然后被丢弃了,所以没有影响这个方法中后续代码执行;
在try中每隔几行打个断点,缩小寻找问题的范围
最终定位到this.applyTransactionTimeout(stmt);出现问题;
进入方法,发现确实是这里出问题
StatementUtil.applyTransactionTimeout(statement, statement.getQueryTimeout(), this.transaction.getTimeout())
挨个排查参数,定位到空指针异常
statement.getQueryTimeout()
去网上查阅资料发现getQueryTimeout一般指超时时间,所以尝试在mybatis-config.xml中添加代码
最后程序正常执行啦!