Monday, October 19, 2009

Oracle JDBC NullPointerException

Got an interesting Oracle JDBC error with Oracle 10.2.0.4 database and thin JDBC driver. I invoked the method java.sql.Statement.setFetchSize(20000) on a java.sql.PreparedStatement object, and when I invoked the executeQuery() method on the object, I got the following stack trace:


java.lang.NullPointerException
at oracle.jdbc.driver.DBConversion._CHARBytesToJavaChars(DBConversion.java:974)
at oracle.jdbc.driver.DBConversion.CHARBytesToJavaChars(DBConversion.java:892)
at oracle.jdbc.driver.T4CCharAccessor.unmarshalOneRow(T4CCharAccessor.java:199)
at oracle.jdbc.driver.T4CTTIrxd.unmarshal(T4CTTIrxd.java:919)
at oracle.jdbc.driver.T4CTTIrxd.unmarshal(T4CTTIrxd.java:843)
at oracle.jdbc.driver.T4C8Oall.receive(T4C8Oall.java:630)
at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:219)
at oracle.jdbc.driver.T4CPreparedStatement.executeForRows(T4CPreparedStatement.java:970)
at oracle.jdbc.driver.OracleStatement.executeMaybeDescribe(OracleStatement.java:1072)
at oracle.jdbc.driver.T4CPreparedStatement.executeMaybeDescribe(T4CPreparedStatement.java:854)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1154)
at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3370)
at oracle.jdbc.driver.OraclePreparedStatement.executeQuery(OraclePreparedStatement.java:3415)
at MyOracleProgram.invokeQuery(MyOracleProgram.java:682)


Well I tried setting the value to be 1000 for the parameter:
setFetchSize(1000)
and problem solved!

The default FetchSize for this version of Oracle appears to be 10, and if you know you will usually be getting back more than 10 rows, by all means set it to to a higher value, but if you try something bigger than 1,000 be careful!



Judging from the name of the method oracle.jdbc.driver.DBConversion._CHARBytesToJavaChars(DBConversion.java:974) in the stack trace, I bet there is a array for the result set with a hard-coded maximum array size of something bigger than 1000, but less than 20000. It would be nice if the oracle jdbc driver would catch this.



Update: Oracle support noticed I was using the ojdbc14.jar file and using Java JDK 1.6; I had to get the ojdbc6.jar file from the Oracle 11.2 JDBC distribution which is certified for JDK 1.6. Works just fine now, with Oracle 10.2 database, and JDK 1.6.