hibernate/hibernate-orm · error · IllegalArgumentException
Positional parameter " + positionLabel + " is not registered
Error message
Positional parameter " + positionLabel + " is not registered with this procedure call
What it means
The positional counterpart of the named lookup: getQueryParameter(int) calls findQueryParameter(positionLabel), which matches only parameters whose name is null and whose position equals the label. No match means IllegalArgumentException 'Positional parameter N is not registered with this procedure call'. Position labels are 1-based as registered.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/procedure/internal/ProcedureParameterMetadataImpl.java:175
@Override
public ProcedureParameterImplementor<?> findQueryParameter(int positionLabel) {
if ( parameters != null ) {
for ( var parameter : parameters ) {
if ( parameter.getName() == null
&& positionLabel == parameter.getPosition() ) {
return parameter;
}
}
}
return null;
}
@Override
public ProcedureParameterImplementor<?> getQueryParameter(int positionLabel) {
final var queryParameter = findQueryParameter( positionLabel );
if ( queryParameter == null ) {
throw new IllegalArgumentException(
"Positional parameter " + positionLabel + " is not registered with this procedure call" );
}
return queryParameter;
}
@Override
public <P> ProcedureParameterImplementor<P> resolve(Parameter<P> parameter) {
if ( parameters != null
&& parameter instanceof ProcedureParameterImplementor<P> procedureParam ) {
for ( var registered : parameters ) {
if ( registered == parameter ) {
return procedureParam;
}
}
}
return null;
}
View on GitHub (pinned to fad1729dce)
Solutions
- Register every positional parameter before binding it: call.registerParameter(2, String.class, ParameterMode.IN)
- Check findQueryParameter(position) (or getParameters() on the Jakarta query) before binding optional parameters
- Reconcile the positions bound with the positions registered — they must be the same 1-based labels
Example fix
// before q.registerStoredProcedureParameter(1, Long.class, ParameterMode.IN); q.setParameter(2, "note"); // position 2 never registered // after q.registerStoredProcedureParameter(1, Long.class, ParameterMode.IN); q.registerStoredProcedureParameter(2, String.class, ParameterMode.IN); q.setParameter(2, "note");
Defensive patterns
Strategy: validation
Validate before calling
// Register every positional parameter before binding q.registerStoredProcedureParameter(1, Long.class, ParameterMode.IN); q.registerStoredProcedureParameter(2, String.class, ParameterMode.IN); q.setParameter(2, "note");
Try / catch
try {
call.getParameterBindings().getBinding(2);
} catch (IllegalArgumentException e) {
// position 2 not registered: add the registration or fix the index
} Prevention
- Keep registrations and bindings for positional parameters in one block so indices stay in sync
- When adding a procedure parameter, update both the registration list and every binding site
- Prefer named parameters for procedures with many optional parameters
When it happens
Trigger: call.getParameterBindings().getBinding(2) or StoredProcedureQuery.setParameter(2, value) when position 2 was never registered, or was registered by name (name != null so positional lookup skips it).
Common situations: Registering positions 1 and 2 but binding position 3; registering parameters by name and then binding by index; off-by-one errors after adding a new parameter to the procedure; copy-pasting setParameter calls from another procedure with more parameters.
Related errors
- Cannot determine the bindable type for procedure parameter %
- Cannot mix named parameter with positional parameter registr
- Cannot mix positional parameter with named parameter registr
- Named parameter [" + name + "] is not registered with this p
- JDBC driver does not support named parameters for setArray.
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/8da4676cec3d962f.
Report an issue: GitHub.