{"record":{"id":"c2b393aceb90dedf","repo":"pentaho/pentaho-kettle","slug":"jobmeta-exception","errorCode":null,"errorMessage":"JobMeta.Exception.UnableToSaveJobInRepositoryRollbackPerformed","messagePattern":"JobMeta\\.Exception\\.UnableToSaveJobInRepositoryRollbackPerformed","errorType":"exception","errorClass":"KettleException","httpStatus":null,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/repository/kdr/delegates/KettleDatabaseRepositoryJobDelegate.java","lineNumber":254,"sourceCode":"        JobHopMeta hi = jobMeta.getJobHop( i );\n        saveJobHopMeta( hi, jobMeta.getObjectId() );\n        if ( monitor != null ) {\n          monitor.worked( 1 );\n        }\n      }\n\n      saveJobParameters( jobMeta );\n\n      // Commit this transaction!!\n      repository.commit();\n\n      jobMeta.clearChanged();\n      if ( monitor != null ) {\n        monitor.done();\n      }\n    } catch ( KettleDatabaseException dbe ) {\n      repository.rollback();\n      throw new KettleException( BaseMessages.getString(\n        PKG, \"JobMeta.Exception.UnableToSaveJobInRepositoryRollbackPerformed\" ), dbe );\n    }\n  }\n\n  /**\n   * Save the parameters of this job to the repository.\n   *\n   * @param rep\n   *          The repository to save to.\n   *\n   * @throws KettleException\n   *           Upon any error.\n   */\n  private void saveJobParameters( JobMeta jobMeta ) throws KettleException {\n    String[] paramKeys = jobMeta.listParameters();\n    for ( int idx = 0; idx < paramKeys.length; idx++ ) {\n      String desc = jobMeta.getParameterDescription( paramKeys[idx] );\n      String defValue = jobMeta.getParameterDefault( paramKeys[idx] );","sourceCodeStart":236,"sourceCodeEnd":272,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/repository/kdr/delegates/KettleDatabaseRepositoryJobDelegate.java#L236-L272","documentation":"Thrown by KettleDatabaseRepositoryJobDelegate.saveJob when a KettleDatabaseException occurs while saving a JobMeta to the database repository. The repository transaction is rolled back first (repository.rollback()), so no partial job rows remain, and the localized message (JobMeta.Exception.UnableToSaveJobInRepositoryRollbackPerformed) indicates the save failed and rollback was performed.","triggerScenarios":"Calling repository.save(jobMeta, path, monitor) when a database error occurs during job insertion: connection failure, constraint violation, too-long field values, oversized job log table, or schema mismatch on r_job/r_jobentry tables.","commonSituations":"Repository RDBMS connection dropped during a large job save; job contains entries with data exceeding column widths; repository schema not upgraded to the current Kettle version; DB in read-only mode or out of space.","solutions":["Inspect the chained KettleDatabaseException (dbe.getCause()) for the concrete SQL error","Verify repository connectivity and retry the save after reconnecting","Check that the repository schema version matches the Kettle version (upgrade if needed)","Look for constraint violations (e.g. duplicate job name/path, oversized fields) and adjust the job or schema"],"exampleFix":"// before\nrepository.save( jobMeta, \"/jobs/etl\", monitor ); // rolls back on DB error\n// after\ntry {\n  repository.save( jobMeta, \"/jobs/etl\", monitor );\n} catch ( KettleException e ) {\n  log.error( \"Job save rolled back. DB cause: \" + e.getCause() );\n  // fix DB issue (connectivity/schema/constraints) and re-save\n}","handlingStrategy":"try-catch","validationCode":"// pre-check schema compatibility and connectivity\nrepository.connect( ... );\n// ensure target path exists\nif ( repo.findDirectory( \"/jobs\" ) == null ) repo.createRepositoryDirectory( repo.getDirectory( \"/\" ), \"jobs\" );","typeGuard":null,"tryCatchPattern":"try {\n  repository.save( jobMeta, path, monitor );\n} catch ( KettleException e ) {\n  // library already rolled back; log e.getCause() (KettleDatabaseException/SQLException)\n  // fix DB issue, then re-save jobMeta\n}","preventionTips":["Keep the repository schema version in sync with the Kettle/Pentaho version","Watch DB connectivity during large saves; retry on transient failure","Check column length limits for job/entry fields and names","Treat the save as atomic: after rollback, re-save the full job rather than patching rows"],"tags":["database","job-save","rollback","transaction"],"backgroundTag":"database-write-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"}