javasqljdbcresultsetcachedrowset

getBytes() working with ResultSet but not CachedRowSet


I have a Derby SQL database in which I have a table containing a blob field that needs to contain a serialized object. I access it through JDBC. The problem is that when I de-serialize the object using a ResultSet all works fine, but if I use a CachedRowSet I get a "Data Type Mismatch" Exception.

Here is the bit of code that works:

ResultSet rs = stmt.executeQuery();
rs.next();
byte[] buf = rs.getBytes("albero");

Here is the alternative bit tha

CachedRowSet crs = null;
ResultSet rs = stmt.executeQuery();
crs = RowSetProvider.newFactory().createCachedRowSet();
crs.populate(rs);
crs.next();    
byte[] buf = crs.getBytes("albero"); 

Could anyone help me understand why this different behaviour? Thanks


Solution

  • The CachedRowSet (assuming the reference implementation com.sun.rowset.CachedRowSetImpl) stores a copy of the data in the ResultSet within the cached rowset. It does this using the getObject method of the result set provided to populate.

    As you indicate that the column is a blob, I assume that getObject will return a Blob and the column type in metadata is BLOB and not a byte array (type VARBINARY or LONGVARBINARY). Therefor the cached rowset will only allow you to retrieve the column as a Blob, and not as a byte[] even if the original result set supports that.

    The JDBC 4.2 specification (Appendix B.6) describes which methods are supported for which types, and for a BLOB, only getBlob (and getObject) are to be supported. However contrary to requirements in the specification a lot of drivers are more lenient and also support getBytes and getBinaryStream for BLOB. In this regard, the CachedRowSetImpl is more strict in its interpretation of JDBC.