hibernate/hibernate-orm · error · IllegalArgumentException
No parameter labelled '?%s' in query with ordinal parameters
Error message
No parameter labelled '?%s' in query with ordinal parameters [%s]
What it means
The ordinal twin of the named-parameter lookup: getQueryParameter(int) searches queryParametersByPosition and, when the label is absent, throws IllegalArgumentException (cause UnknownParameterException) listing the ordinal labels the query actually declares. It fires from setParameter(position, ...) or getParameter(position) with a label the query never defined.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/query/internal/ParameterMetadataImpl.java:306
@Override
public QueryParameterImplementor<?> findQueryParameter(int positionLabel) {
return queryParametersByPosition == null ? null : queryParametersByPosition.get( positionLabel );
}
@Override
public QueryParameterImplementor<?> getQueryParameter(int positionLabel) {
final var queryParameter = findQueryParameter( positionLabel );
if ( queryParameter != null ) {
return queryParameter;
}
else {
final String errorMessage = String.format(
Locale.ROOT,
"No parameter labelled '?%s' in query with ordinal parameters [%s]",
positionLabel,
StringHelper.join( ", ", getOrdinalParameterLabels() )
);
throw new IllegalArgumentException(
errorMessage,
new UnknownParameterException( errorMessage )
);
}
}
}
View on GitHub (pinned to fad1729dce)
Solutions
- Align the bind position with the labels listed in the message (query.getParameterMetadata().getOrdinalParameterLabels()).
- Renumber the HQL labels and the setParameter calls together so they stay 1..N.
- Prefer named parameters to avoid position/index coupling entirely.
Example fix
// before
var q = session.createQuery("from Person p where p.age > ?1", Person.class);
q.setParameter(2, 30); // throws: only '?1' exists
// after
q.setParameter(1, 30); Defensive patterns
Strategy: validation
Validate before calling
static void requireOrdinalParam(org.hibernate.query.Query<?> q, int position) {
if (!q.getParameterMetadata().getOrdinalParameterLabels().contains(position))
throw new IllegalArgumentException("Query declares no parameter ?" + position
+ " - declared: " + q.getParameterMetadata().getOrdinalParameterLabels());
} Prevention
- Keep ordinal labels 1..N and bind them from one loop over a value array.
- Update all setParameter call sites whenever a predicate is added or removed.
- Prefer named parameters to break the positional coupling.
When it happens
Trigger: Calling setParameter(2, value) on a query that declares only ?1; binding to a label that was removed when the query was edited; using ordinal binding on a query that only has named parameters.
Common situations: Editing a query and dropping a predicate without renumbering or updating bind calls; copy-pasted binding blocks between queries with different parameter counts; mixing ?1-style binding with queries that use :name.
Related errors
- The parameter at position{position} has no argument
- Ordinal parameter labels start from '?%s' (ordinal parameter
- Gap between '?%s' and '?%s' in ordinal parameter labels [%s]
- No parameter named ':%s' in query with named parameters [%s]
- No argument for ordinal parameter '?{}'
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/385f89d6a9b5477f.
Report an issue: GitHub.