{"record":{"id":"d23eb5c87ce72f6e","repo":"pentaho/pentaho-kettle","slug":"transdependency-exception-unabletosavetransformationdepency","errorCode":null,"errorMessage":"TransDependency.Exception.UnableToSaveTransformationDepency","messagePattern":"TransDependency\\.Exception\\.UnableToSaveTransformationDepency","errorType":"exception","errorClass":"KettleException","httpStatus":null,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/repository/kdr/delegates/KettleDatabaseRepositoryTransDelegate.java","lineNumber":1086,"sourceCode":"      }\n\n      return transDependency;\n    } catch ( KettleException dbe ) {\n      throw new KettleException( BaseMessages.getString(\n        PKG, \"TransDependency.Exception.UnableToLoadTransformationDependency\" )\n        + id_dependency, dbe );\n    }\n  }\n\n  public void saveTransDependency( TransDependency transDependency, ObjectId id_transformation ) throws KettleException {\n    try {\n      ObjectId id_database =\n        transDependency.getDatabase() == null ? null : transDependency.getDatabase().getObjectId();\n\n      transDependency.setObjectId( insertDependency( id_transformation, id_database, transDependency\n        .getTablename(), transDependency.getFieldname() ) );\n    } catch ( KettleException dbe ) {\n      throw new KettleException( BaseMessages.getString(\n        PKG, \"TransDependency.Exception.UnableToSaveTransformationDepency\" )\n        + id_transformation, dbe );\n    }\n  }\n\n  public void saveTransHopMeta( TransHopMeta transHopMeta, ObjectId id_transformation ) throws KettleException {\n    try {\n      // See if a transformation hop with the same fromstep and tostep is\n      // already available...\n      ObjectId id_step_from = transHopMeta.getFromStep() == null ? null : transHopMeta.getFromStep().getObjectId();\n      ObjectId id_step_to = transHopMeta.getToStep() == null ? null : transHopMeta.getToStep().getObjectId();\n\n      // Insert new transMeta hop in repository\n      transHopMeta.setObjectId( insertTransHop( id_transformation, id_step_from, id_step_to, transHopMeta\n        .isEnabled() ) );\n    } catch ( KettleDatabaseException dbe ) {\n      throw new KettleException( BaseMessages.getString(\n        PKG, \"TransHopMeta.Exception.UnableToSaveTransformationHopInfo\" )","sourceCodeStart":1068,"sourceCodeEnd":1104,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/repository/kdr/delegates/KettleDatabaseRepositoryTransDelegate.java#L1068-L1104","documentation":"Thrown by saveTransDependency() when inserting a transformation dependency row into the repository fails with a KettleException. The message includes the transformation ObjectId being saved. It wraps failures of insertDependency(), typically SQL insert errors or constraint violations.","triggerScenarios":"Saving a TransMeta (or explicitly calling saveTransDependency) where insertDependency(id_transformation, id_database, tablename, fieldname) fails: FK violation because the transformation or database id does not exist, null tablename/fieldname in a schema that disallows it, or connection failure.","commonSituations":"Saving a transformation to a repository where the referenced DatabaseMeta was never saved, transaction rollback after partial save, or DB storage full / read-only account.","solutions":["Ensure the transformation and its database connections are saved before dependencies (ids must exist)","Check the chained cause for SQL constraint violations and fix the missing parent rows","Verify tablename/fieldname values are populated on the TransDependency","Confirm the DB user has INSERT privilege on R_DEPENDENCY"],"exampleFix":"// before\nTransDependency dep = new TransDependency(null, \"tbl\", \"fld\"); // databaseMeta null\nrep.save(transMeta, \"comment\", null);\n\n// after\ndep.setDatabase(dbMeta); // ensure saved DatabaseMeta with ObjectId\nrep.save(databases); // persist connection first\nrep.save(transMeta, \"comment\", null);","handlingStrategy":"try-catch","validationCode":"// Java: pre-save checks before persisting dependencies\nif (transDependency.getDatabase() == null\n    || transDependency.getDatabase().getObjectId() == null) {\n  throw new IllegalStateException(\"Save the DatabaseMeta before saving dependencies\");\n}\nif (transDependency.getTablename() == null || transDependency.getFieldname() == null) {\n  throw new IllegalStateException(\"Dependency table/field must be set\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  delegate.saveTransDependency(dep, transId);\n} catch (KettleException e) {\n  log.error(\"Dependency save failed for transformation \" + transId + \": \" + e.getCause(), e);\n  throw e; // abort transactional save to keep repo consistent\n}","preventionTips":["Always save database connections before the transformation that depends on them","Ensure parent ObjectIds (transformation, database) are non-null before inserts","Use the repository's save() API rather than delegate methods out of order","Verify INSERT grants on R_DEPENDENCY for the repository account"],"tags":["database","repository","kettle","dependency","insert"],"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"}