{"record":{"id":"4e9dad75d1de9086","repo":"tursodatabase/turso","slug":"resultset-closed","errorCode":null,"errorMessage":"ResultSet closed","messagePattern":"ResultSet closed","errorType":"exception","errorClass":"SQLException","httpStatus":null,"severity":"error","filePath":"bindings/java/src/main/java/tech/turso/core/TursoResultSet.java","lineNumber":140,"sourceCode":"\n  /** Gets the current row number (0-based, 0 means before first row). */\n  public int getRow() {\n    return row;\n  }\n\n  /**\n   * Checks the status of the result set.\n   *\n   * @return true if it's ready to iterate over the result set; false otherwise.\n   */\n  public boolean isOpen() {\n    return open;\n  }\n\n  /** @throws SQLException if not {@link #open} */\n  public void checkOpen() throws SQLException {\n    if (!open) {\n      throw new SQLException(\"ResultSet closed\");\n    }\n  }\n\n  public void close() throws SQLException {\n    this.open = false;\n  }\n\n  public Object get(String columnName) throws SQLException {\n    final int columnsLength = this.columnNames.length;\n    for (int i = 0; i < columnsLength; i++) {\n      if (this.columnNames[i].equals(columnName)) {\n        return get(i + 1);\n      }\n    }\n\n    throw new SQLException(\"column name \" + columnName + \" not found\");\n  }\n","sourceCodeStart":122,"sourceCodeEnd":158,"githubUrl":"https://github.com/tursodatabase/turso/blob/bad083fafbefdeae9a42ec19bdaaad8918dcf411/bindings/java/src/main/java/tech/turso/core/TursoResultSet.java#L122-L158","documentation":"TursoResultSet.checkOpen() is the shared guard for result-set operations: it throws 'ResultSet closed' whenever open is false. The set is closed by close(), by statement.close() (which delegates to resultSet.close()), by reset() replacing it, or by next() after an invalid step state.","triggerScenarios":"Any guarded read/metadata operation on a ResultSet after rs.close(), after the owning statement was closed, or after a prior step error flipped open to false.","commonSituations":"Extracting row values in a helper method called after the statement's try-with-resources block exited; finally-block logging of the last row; frameworks closing statements eagerly before materializing results.","solutions":["Read all values inside the statement/ResultSet lifetime, before either is closed","Check rs.isOpen() (or JDBC isClosed()) before touching a set whose state is uncertain","Copy needed values into POJOs/lists while iterating, then close"],"exampleFix":"// before\ntry (Statement st = conn.createStatement()) {\n  ResultSet rs = st.executeQuery(q);\n  rs.close();\n  return rs.get(1); // throws: ResultSet closed\n}\n\n// after\ntry (Statement st = conn.createStatement()) {\n  ResultSet rs = st.executeQuery(q);\n  return rs.next() ? rs.get(1) : null;\n}","handlingStrategy":"validation","validationCode":"if (rs.isOpen()) {\n  Object v = rs.get(1);\n}","typeGuard":null,"tryCatchPattern":"try {\n  return rs.get(1);\n} catch (SQLException e) {\n  if (\"ResultSet closed\".equals(e.getMessage())) {\n    return null; // or re-execute the query for a fresh set\n  }\n  throw e;\n}","preventionTips":["Extract all values inside the statement's try block, before resources close","Check isOpen()/isClosed() before reading from sets held across method boundaries","Materialize rows into objects first, then close — never keep live ResultSets around"],"tags":["java","jdbc","resultset","lifecycle","bindings"],"backgroundTag":"resultset-already-closed","analyzedSha":"bad083fafbefdeae9a42ec19bdaaad8918dcf411","analyzedAt":"2026-08-16T23:12:11.798Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}