apache/shardingsphere · error · ResultSetClosedException
2
2
Error message
Result set has been closed.
What it means
ResultSetClosedException (code 2) thrown by DatabaseMetaDataResultSet.checkClosed when any accessor is invoked after the metadata result set was closed. ShardingSphere explicitly guards closed state because this result set is a self-contained object over cached metadata rows.
Source
Thrown at jdbc/src/main/java/org/apache/shardingsphere/driver/jdbc/core/resultset/DatabaseMetaDataResultSet.java:422
@Override
public int getFetchSize() throws SQLException {
return resultSet.getFetchSize();
}
@Override
public void setFetchSize(final int rows) throws SQLException {
resultSet.setFetchSize(rows);
}
@Override
public boolean isClosed() {
return closed;
}
private void checkClosed() throws SQLException {
if (closed) {
throw new ResultSetClosedException().toSQLException();
}
}
private void checkColumnIndex(final int columnIndex) throws SQLException {
if (columnIndex < 1 || columnIndex > resultSetMetaData.getColumnCount()) {
throw new ColumnIndexOutOfRangeException(columnIndex).toSQLException();
}
}
@EqualsAndHashCode
private static final class DatabaseMetaDataObject {
private final List<Object> objects;
private DatabaseMetaDataObject(final int columnCount) {
objects = new ArrayList<>(columnCount);
}
View on GitHub (pinned to e952770a21)
Solutions
- Copy the needed rows out of the metadata ResultSet (into a list/DTO) before leaving the try-with-resources block.
- Ensure only the owner that opened the ResultSet closes it, and never access it afterwards.
- Remove duplicate close() calls or overly broad try-with-resources scoping.
Example fix
// before
try (ResultSet rs = meta.getTables(null, null, "%", null)) { tables = rs; }
String s = tables.getString(1); // closed
// after
try (ResultSet rs = meta.getTables(null, null, "%", null)) {
while (rs.next()) { names.add(rs.getString("TABLE_NAME")); }
} Defensive patterns
Strategy: validation
Validate before calling
if (rs.isClosed()) throw new IllegalStateException("result set already closed"); Try / catch
catch (SQLException ex) { if (rs != null && rs.isClosed()) reopenOrRefetch(); else throw ex; } Prevention
- Copy metadata rows out before the ResultSet leaves scope
- Single-owner close discipline
- Never cache ResultSets beyond the fetch operation
When it happens
Trigger: Calling any method guarded by checkClosed() (findColumn, getType, getConcurrency, getters, etc.) on a DatabaseMetaData ResultSet after close() was called — often implicitly by frameworks or try-with-resources scoping.
Common situations: Using a metadata ResultSet after the enclosing try block closed it; caching a ResultSet beyond its scope; double iteration where the first loop closes; helper utilities that close result sets eagerly.
Related errors
AI-assisted analysis of apache/shardingsphere@e952770a21 (2026-08-14).
Data as JSON: /api/errors/82a12672df53d079.
Report an issue: GitHub.