hibernate/hibernate-orm · error · UnknownParameterException
Unable to locate parameter `%s.%s` for %s - %s : %s
Error message
Unable to locate parameter `%s.%s` for %s - %s : %s
What it means
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.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/sql/model/MutationOperation.java:99
TableMapping getTableDetails();
/**
* Find the JDBC parameter to be used for the specified column.
*
* @return The descriptor, or null if none match.
*
* @see #getJdbcValueDescriptor
*/
JdbcValueDescriptor findValueDescriptor(String columnName, ParameterUsage usage);
/**
* Form of {@link #findValueDescriptor}, throwing an exception if not found as opposed
* to simply returning null
*/
default JdbcValueDescriptor getJdbcValueDescriptor(String columnName, ParameterUsage usage) {
final JdbcValueDescriptor parameterDescriptor = findValueDescriptor( columnName, usage );
if ( parameterDescriptor == null ) {
throw new UnknownParameterException( getMutationType(), getMutationTarget(), getTableDetails().getTableName(), columnName, usage );
}
return parameterDescriptor;
}
@Override
default String resolvePhysicalTableName(String tableName) {
assert getTableDetails().getTableName().equals( tableName );
return tableName;
}
@Override
default JdbcValueDescriptor resolveValueDescriptor(String tableName, String columnName, ParameterUsage usage) {
assert getTableDetails().getTableName().equals( tableName );
return findValueDescriptor( columnName, usage );
}
}
View on GitHub (pinned to fad1729dce)
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
Example fix
// before @SQLDelete( sql = "UPDATE Company SET deleted = true WHERE id = ?" ) // missing version predicate // after @SQLDelete( sql = "UPDATE Company SET deleted = true WHERE id = ? AND version = ?" )
Defensive patterns
Strategy: validation
Validate before calling
JdbcValueDescriptor d = operation.findValueDescriptor( columnName, usage );
if ( d == null ) {
// column not part of this mutation's SQL: skip or rebuild the operation
} else { bind( d ); } Prevention
- 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)
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Unable to locate JdbcValueDescriptor for column `%s`
- write expression must contain exactly one value placeholder
- Unable to locate parameter `%s.%s` for %s - %s : %s
- Could not locate binding [%s : %s]
- Unable to resolve TableMapping for selectable - %s
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/075d3fbb76bfb3b1.
Report an issue: GitHub.