{"record":{"id":"99ea5e8c081b4753","repo":"pentaho/pentaho-kettle","slug":"error-closing-connection-while-searching-primary-keys-in","errorCode":null,"errorMessage":"Error closing connection while searching primary keys in table []","messagePattern":"Error closing connection while searching primary keys in table \\[\\]","errorType":"exception","errorClass":"KettleDatabaseException","httpStatus":null,"severity":"warning","filePath":"core/src/main/java/org/pentaho/di/core/database/Database.java","lineNumber":5153,"sourceCode":"      while ( allkeys.next() ) {\n        String keyname = allkeys.getString( \"PK_NAME\" );\n        String columnName = allkeys.getString( \"COLUMN_NAME\" );\n        if ( !names.contains( columnName ) ) {\n          names.add( columnName );\n        }\n        if ( log.isRowLevel() ) {\n          log.logRowlevel( toString(), \"getting key : \" + keyname + \" on column \" + columnName );\n        }\n      }\n    } catch ( SQLException e ) {\n      log.logError( toString(), \"Error getting primary keys columns from table [\" + tablename + \"]\" );\n    } finally {\n      try {\n        if ( allkeys != null ) {\n          allkeys.close();\n        }\n      } catch ( SQLException e ) {\n        throw new KettleDatabaseException( \"Error closing connection while searching primary keys in table [\"\n          + tablename + \"]\", e );\n      }\n    }\n    return names.toArray( new String[ names.size() ] );\n  }\n\n  /**\n   * Return all sequence names from connection\n   *\n   * @return The sequences name list.\n   * @throws KettleDatabaseException\n   */\n  public String[] getSequences() throws KettleDatabaseException {\n    if ( databaseMeta.supportsSequences() ) {\n      String sql = databaseMeta.getSQLListOfSequences();\n      if ( sql != null ) {\n        List<Object[]> seqs = getRows( sql, 0 );\n        String[] str = new String[ seqs.size() ];","sourceCodeStart":5135,"sourceCodeEnd":5171,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/core/src/main/java/org/pentaho/di/core/database/Database.java#L5135-L5171","documentation":"Thrown in the finally block of Database's primary-key lookup (Database.java:5153, getTableFields/getLookup of primary keys) when closing the ResultSet holding the key metadata fails with a SQLException. The primary keys may still have been read — the failure is in resource cleanup, and the message includes the table name.","triggerScenarios":"Calling the primary-key retrieval API (e.g. getPrimaryKeyColumnNames / getTableFields path that iterates dbmd.getPrimaryKeys) and the allkeys ResultSet.close() in finally throws — connection dropped or driver error during metadata close.","commonSituations":"Firewall/timeout killing the connection between metadata fetch and close; flaky drivers throwing on closed result sets; calling PK lookup right after a connection timeout in long-running jobs.","solutions":["Check the wrapped SQLException cause — if the keys were read successfully, treat this as a cleanup-only failure","Validate/recycle connections with validation queries to avoid mid-query disconnects","Increase socket/network timeouts for metadata-heavy queries against slow catalogs","Avoid calling PK lookup on connections that just failed another operation","Retry the primary-key lookup with a fresh connection if the result was lost"],"exampleFix":"// before\n} catch ( SQLException e ) {\n  throw new KettleDatabaseException( \"Error closing connection while searching primary keys in table [\"\n    + tablename + \"]\", e );\n}\n// after\n} catch ( SQLException e ) {\n  log.logError( \"Error closing primary-key result set for table [\" + tablename + \"]\", e ); // keys already collected\n}\nreturn names.toArray( new String[ names.size() ] );","handlingStrategy":"try-catch","validationCode":"if ( database.getConnection() == null || database.getConnection().isClosed() ) {\n  database.connect(); // refresh connection before metadata lookup\n}","typeGuard":null,"tryCatchPattern":"try {\n  String[] keys = getPrimaryKeys( tablename );\n} catch ( KettleDatabaseException e ) {\n  if ( names.size() > 0 ) {\n    // keys were read; cleanup failure only — proceed with names\n  } else {\n    throw e; // real failure, keys lost\n  }\n}","preventionTips":["Use connection validation to recycle stale connections before metadata queries","Set generous socket timeouts for catalog queries on slow DBs","Prefer structured cleanup over throwing from finally blocks","Retry metadata lookups on fresh connections after disconnects"],"tags":["jdbc","database","metadata","primary-keys","cleanup"],"backgroundTag":"database-query-failed","analyzedSha":"f3058517a153da500bf4551f46d79b91bf8ec552","analyzedAt":"2026-09-13T14:04:16.340Z","contentChangedAt":"2026-09-13T14:04:16.340Z","schemaVersion":2},"datasetVersion":"2026-09-20T23:17:15.980Z"}