| Bug #55340 | initializeResultsMetadataFromCache fails on second call to stored proc | ||
|---|---|---|---|
| Submitted: | 18 Jul 2010 8:04 | Modified: | 25 Nov 2013 20:13 |
| Reporter: | Bill Culp | Email Updates: | |
| Status: | Closed | Impact on me: | |
| Category: | Connector / J | Severity: | S2 (Serious) |
| Version: | 5.1.13 | OS: | MacOS |
| Assigned to: | Filipe Silva | CPU Architecture: | Any |
| Tags: | Connector/J | ||
[23 Aug 2010 7:41]
Tonci Grgin
Thanks Bill. Verified on the basis of Mark's analysis. Could be tough to fix though.
[25 Nov 2013 20:13]
Daniel So
Added an entry to the Connector/J 5.1.28 changelog: "With cacheResultSetMetadata=true, cacheCallableStmts=true, and cachePrepStmts=true, if a stored procedure that returns a result set was called, calling the stored procedure a second time resulted in a null pointer exception being thrown for initializeResultsMetadataFromCache."

Description: Caused by: java.lang.NullPointerException at com.mysql.jdbc.ConnectionImpl.initializeResultsMetadataFromCache(ConnectionImpl.java:5486) When enabling cacheResultSetMetadata=true&cacheCallableStmts=true&cachePrepStmts=true If you call a stored procedure that returns a result set, the second time you call it a null pointer is thrown in the connection impl. How to repeat: Enable the properties cacheResultSetMetadata=true&cacheCallableStmts=true&cachePrepStmts=true Call a stored procedure that returns a result set. Return the connection to the pool or close. prepare the statement again with the same sql and call execute(). Caused by: java.lang.NullPointerException at com.mysql.jdbc.ConnectionImpl.initializeResultsMetadataFromCache(ConnectionImpl.java:5486) at com.mysql.jdbc.PreparedStatement.execute(PreparedStatement.java:1370) at com.mysql.jdbc.CallableStatement.execute(CallableStatement.java:879) at org.apache.tomcat.dbcp.dbcp.DelegatingPreparedStatement.execute(DelegatingPreparedStatement.java:169) Suggested fix: ----> LINE 1369 PreparedStatement.java if (cachedMetadata != null) { locallyScopedConn.initializeResultsMetadataFromCache(this.originalSql, cachedMetadata, this.results); <---------------- this is wrong } else { if (rs.reallyResult() && locallyScopedConn.getCacheResultSetMetadata()) { locallyScopedConn.initializeResultsMetadataFromCache(this.originalSql, null /* will be created */, rs); <---------------- this is right } } Make the call pass in rs and not this.results; this.results cant possibly be populated in this logic