hibernate/hibernate-orm · error · HibernateException
Unable to locate JdbcValueDescriptor for column `%s`
Error message
Unable to locate JdbcValueDescriptor for column `%s`
What it means
JdbcValueBindings.bindValue maps a (column, ParameterUsage) pair onto a parameter slot of the prepared mutation. When a bind template is active and findSlot(columnName, parameterUsage) returns null, the mutation statement has no parameter for that column/usage combination, so the value cannot be attached and HibernateException is thrown. It is almost always a name or usage mismatch between what the caller binds and what the mutation SQL declares.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/action/queue/spi/bind/JdbcValueBindings.java:116
Locale.ROOT,
"Unable to bind parameter #%s - %s",
slot.jdbcPosition(),
valuesBySlot[i]
)
);
}
}
}
public static Object resolveValue(Object value) {
return value instanceof DelayedValueAccess handle ? handle.get() : value;
}
public void bindValue(Object columnValue, String columnName, ParameterUsage parameterUsage) {
if ( bindTemplate != null ) {
final BindSlot slot = bindTemplate.findSlot( columnName, parameterUsage );
if ( slot == null ) {
throw new HibernateException( "Unable to locate JdbcValueDescriptor for column `" + columnName + "`" );
}
if ( !boundSlots[slot.index()] ) {
valuesBySlot[slot.index()] = columnValue;
boundSlots[slot.index()] = true;
}
return;
}
final var jdbcValueDescriptor = jdbcValueDescriptorAccess.resolveValueDescriptor(
tableDescriptor.name(),
columnName,
parameterUsage
);
if ( jdbcValueDescriptor == null ) {
throw new HibernateException( "Unable to locate JdbcValueDescriptor for column `" + columnName + "`" );
}
bindingGroup.bindValue( columnName, columnValue, jdbcValueDescriptor );
}View on GitHub (pinned to fad1729dce)
Solutions
- Log the mutation SQL and bind exactly the column names it declares, including case and quoting.
- Pass the ParameterUsage that matches the parameter kind being bound (REGULAR, RETURNING, LIMIT...).
- In custom binding code, derive names from the template/descriptor set instead of hard-coded literals.
- If no custom code is involved, upgrade Hibernate - descriptor resolution regressions have occurred across versions.
Example fix
// before bindings.bindValue(value, "ACCOUNT_ID", ParameterUsage.REGULAR); // mapped as 'accountId' // after bindings.bindValue(value, "accountId", ParameterUsage.REGULAR);
Defensive patterns
Strategy: validation
Validate before calling
// derive column names from the mapping instead of hard-coded literals
for (SelectableMapping col : mutationTarget.getSelectableMappings()) {
bindings.bindValue(values.get(col.getSelectionExpression()), col.getSelectionExpression(), ParameterUsage.REGULAR);
} Prevention
- Bind with the exact selection expression from the mapping, preserving case and quoting
- Match the ParameterUsage to the parameter kind (REGULAR vs RETURNING vs LIMIT)
- Add a unit test that binds every mapped column of each mutated table
When it happens
Trigger: Calling bindValue with a column name that differs from the mapped name (case differences on case-sensitive databases, quoted identifiers, typos) or with the wrong ParameterUsage (e.g. binding a value as REGULAR when the parameter is RETURNING); custom mutation code binding columns that are not in the generated statement.
Common situations: Custom MutationExecutor / PreparableMutationOperation implementations; integrations that bind audit or revision columns; column renames in the mapping while stale code binds the old literal name.
Related errors
- Unable to locate parameter `%s.%s` for %s - %s : %s
- Unable to locate parameter `%s.%s` for %s - %s : %s
- cannot recreate collection while filter is enabled: " + coll
- Instance of '" + entityName + "' references an unsaved trans
- Action was vetoed: " + entityAction
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/01ef856767f3cebc.
Report an issue: GitHub.