After returning a pooled connection to the pool and getting it again a NullPointerException is thrown when a clob field is accessed again. This may be related to the following post:
http://mail-archives.apache.org/mod_mbox/db-derby-user/200803.mbox/%3C47CD3431.5020205@sun.com%3E
Here is the stack trace:
java.lang.NullPointerException
at org.apache.derby.client.am.PreparedStatement.setIntX(Unknown Source)
at org.apache.derby.client.am.CallableLocatorProcedures.clobGetLength(Unknown Source)
at org.apache.derby.client.am.Clob.getLocatorLength(Unknown Source)
at org.apache.derby.client.am.Lob.sqlLength(Unknown Source)
at org.apache.derby.client.am.Clob.length(Unknown Source)
at org.apache.derby.client.am.Cursor.getString(Unknown Source)
at org.apache.derby.client.am.ResultSet.getString(Unknown Source)
at derbyerr.Main.main(Main.java:65)
Here is the code to reproduce the problem:
package derbyerr;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.sql.PooledConnection;
import org.apache.derby.jdbc.ClientConnectionPoolDataSource;
public class Main {
public static void main (String[] args) {
org.apache.derby.tools.sysinfo.main (args) ;
ClientConnectionPoolDataSource creator = new ClientConnectionPoolDataSource () ;
// There should be an empty db named testdb
creator.setDatabaseName ("testdb") ;
try {
PooledConnection pc = creator.getPooledConnection () ;
Connection c = pc.getConnection () ;
PreparedStatement ps ;
ResultSet rs ;
String s ;
// Drop the table "test", if it exsists
try {
ps = c.prepareStatement ("drop table test") ;
ps.execute () ;
ps.close () ;
} catch (Exception e) {
}
// Create a test table with a clob field
ps = c.prepareStatement ("create table test (pkey varchar(255) not null primary key, value clob)") ;
ps.execute () ;
ps.close () ;
// Insert a record
ps = c.prepareStatement ("insert into test values ('123', 'abc')") ;
ps.execute () ;
ps.close () ;
// Query the record and...
ps = c.prepareStatement ("select * from test") ;
rs = ps.executeQuery () ;
rs.next () ;
// ...access the clob field - this works
s = rs.getString (2) ;
assert s.equals ("abc") ;
rs.close () ;
ps.close () ;
// Simulate connection pooling: close the connection and get it again
c.close () ;
c = pc.getConnection () ;
// Now again query the record...
ps = c.prepareStatement ("select * from test") ;
rs = ps.executeQuery () ;
rs.next () ;
// ...and access the clob - this fails
s = rs.getString (2) ;
assert s.equals ("abc") ;
rs.close () ;
ps.close () ;
} catch (Exception e) {
e.printStackTrace () ;
}
}
}
At the moment I don't have much to offer, but you can run with JDBC statement caching as a workaround by adding "creator.setMaxStatements(<how-many-statements-you-want-to-cache>);".
Please note that the client-side JDBC statement cache is not ready for production with 10.4.1.3. There were some bugs on the server in how the connections were handled, causing a resource leak that lead to increased GC overhead.
The cause of the NPE is that the parameter meta data has been nulled out and not been reset. I hope to be able to have a closer look on Monday.