使用CachedRowSet更新Derby可空日期字段为Null报错求助
问题确认与解决方案
这是OpenJDK的CachedRowSet实现与Apache Derby 16.1交互时的兼容性Bug:CachedRowSet在处理DATE类型字段的null更新时,错误地向Derby驱动传递了INTEGER类型的SQL标识,导致驱动触发SQLDataException类型转换错误。从报错栈跟踪能看到,问题出在CachedRowSetWriter.updateOriginalRow调用EmbedPreparedStatement.setNull时的类型参数不匹配。
可行解决方法
方法1:使用updateObject明确指定SQL类型
替换原来的updateDate(null)或updateNull调用,改用updateObject并指定Types.DATE,强制传递正确的类型标识:
cached_RowSet.absolute(row + 1); // 明确指定SQL类型为DATE,避免类型匹配错误 cached_RowSet.updateObject("NullableDateColumn", null, java.sql.Types.DATE); cached_RowSet.updateRow(); cached_RowSet.acceptChanges();
这个方法直接有效,能绕过CachedRowSet的类型推断缺陷,让Derby驱动正确识别null值的目标字段类型。
方法2:升级依赖版本
- 尝试升级Apache Derby到最新稳定版(如10.16.x之后的版本),部分后续版本修复了与JDBC RowSet的兼容性问题。
- 检查OpenJDK版本,部分较新的OpenJDK 17更新补丁可能修复了CachedRowSet的类型处理逻辑。
方法3:临时绕开CachedRowSet的自动更新逻辑
如果必须保留原有CachedRowSet操作流程,可以在acceptChanges前手动执行原生SQL更新(此方式会失去CachedRowSet的缓存优势,仅作为应急方案):
// 在CachedRowSet定位行后,手动执行原生SQL更新 try (Connection conn = DriverManager.getConnection(DATABASE_URL, USERNAME, PASSWORD)) { String updateSql = "UPDATE PROJECTS SET NullableDateColumn = ? WHERE id = ?"; try (PreparedStatement pstmt = conn.prepareStatement(updateSql)) { pstmt.setNull(1, java.sql.Types.DATE); pstmt.setInt(2, cached_RowSet.getInt("id")); // 假设主键为id字段 pstmt.executeUpdate(); } // 重新加载CachedRowSet数据同步状态 cached_RowSet.execute(); }
内容的提问来源于stack exchange,提问作者ironman
相关产品推荐
相关产品推荐

