{"record":{"id":"075d3fbb76bfb3b1","repo":"hibernate/hibernate-orm","slug":"unable-to-locate-parameter-s-s-for-s-s-075d3f","errorCode":null,"errorMessage":"Unable to locate parameter `%s.%s` for %s - %s : %s","messagePattern":"Unable to locate parameter `(.+?)\\.(.+?)` for (.+?) - (.+?) : (.+?)","errorType":"exception","errorClass":"UnknownParameterException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/sql/model/MutationOperation.java","lineNumber":99,"sourceCode":"\tTableMapping getTableDetails();\n\n\t/**\n\t * Find the JDBC parameter to be used for the specified column.\n\t *\n\t * @return The descriptor, or null if none match.\n\t *\n\t * @see #getJdbcValueDescriptor\n\t */\n\tJdbcValueDescriptor findValueDescriptor(String columnName, ParameterUsage usage);\n\n\t/**\n\t * Form of {@link #findValueDescriptor}, throwing an exception if not found as opposed\n\t * to simply returning null\n\t */\n\tdefault JdbcValueDescriptor getJdbcValueDescriptor(String columnName, ParameterUsage usage) {\n\t\tfinal JdbcValueDescriptor parameterDescriptor = findValueDescriptor( columnName, usage );\n\t\tif ( parameterDescriptor == null ) {\n\t\t\tthrow new UnknownParameterException( getMutationType(), getMutationTarget(), getTableDetails().getTableName(), columnName, usage );\n\t\t}\n\t\treturn parameterDescriptor;\n\t}\n\n\t@Override\n\tdefault String resolvePhysicalTableName(String tableName) {\n\t\tassert getTableDetails().getTableName().equals( tableName );\n\t\treturn tableName;\n\t}\n\n\t@Override\n\tdefault JdbcValueDescriptor resolveValueDescriptor(String tableName, String columnName, ParameterUsage usage) {\n\t\tassert getTableDetails().getTableName().equals( tableName );\n\t\treturn findValueDescriptor( columnName, usage );\n\t}\n}\n","sourceCodeStart":81,"sourceCodeEnd":116,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/sql/model/MutationOperation.java#L81-L116","documentation":"MutationOperation.getJdbcValueDescriptor(columnName, usage) is the throwing variant of findValueDescriptor: it locates the JdbcValueDescriptor (JDBC position and type) for a column under a specific ParameterUsage (SET, WHERE, VERSION, RETURNING) of an insert/update/delete operation. If no descriptor matches, it throws UnknownParameterException carrying mutation type, target, table, column and usage - meaning the requested column/usage combination is not part of that operation's SQL.","triggerScenarios":"Binding a mutation built from custom SQL (@SQLInsert/@SQLUpdate/@SQLDelete) that lacks a placeholder for a column; requesting ParameterUsage.VERSION on a non-versioned operation; custom MutationOperation/MutationExecutor implementations resolving descriptors by column name for columns outside the mutated table; secondary-table columns resolved against the primary-table mutation.","commonSituations":"Custom DML annotations with fewer '?' placeholders than mapped columns require; schema/mapping drift after adding columns without regenerating custom SQL; custom flush pipelines; upgrades that reclassify parameter usage.","solutions":["Align custom SQL with the mapping: every participating mapped column needs its placeholder in the @SQL* statement","Check the requested usage - VERSION parameters exist only on versioned mutations, RETURNING only where supported","Call findValueDescriptor(...) and handle null when the column may legitimately be absent, instead of getJdbcValueDescriptor(...)","Regenerate/verify custom DML after adding, removing or reordering entity columns"],"exampleFix":"// before\n@SQLDelete( sql = \"UPDATE Company SET deleted = true WHERE id = ?\" ) // missing version predicate\n\n// after\n@SQLDelete( sql = \"UPDATE Company SET deleted = true WHERE id = ? AND version = ?\" )","handlingStrategy":"validation","validationCode":"JdbcValueDescriptor d = operation.findValueDescriptor( columnName, usage );\nif ( d == null ) {\n    // column not part of this mutation's SQL: skip or rebuild the operation\n} else { bind( d ); }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Prefer findValueDescriptor with a null check over the throwing get variant when absence is possible","Keep custom @SQL* statements in sync with the mapping - one placeholder per participating column","Request only usages the operation actually has (VERSION on versioned mutations, RETURNING where supported)"],"tags":["hibernate","orm","mutation","custom-sql","flush"],"backgroundTag":"mutation-parameter-missing","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}