hibernate/hibernate-orm · error · ParameterLabelException
Ordinal parameter labels start from '?%s' (ordinal parameter
Error message
Ordinal parameter labels start from '?%s' (ordinal parameters must be labelled from '?1')
What it means
When Hibernate parses HQL/JPQL it validates that ordinal parameter labels are consecutive integers starting at 1. ParameterMetadataImpl.verifyOrdinalParamLabels sorts the labels and throws ParameterLabelException at query creation when the smallest label is not 1. This matches the JPA spec and is stricter than Hibernate 5, which tolerated arbitrary positional labels.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/query/internal/ParameterMetadataImpl.java:135
queryParameters.put( queryParameter, emptyList() );
tempQueryParametersByName.put( queryParameter.getName(), queryParameter );
}
}
queryParametersByPosition = tempQueryParametersByPosition;
queryParametersByName = tempQueryParametersByName;
queryParameterBindingsTemplate = QueryParameterBindingsImpl.from( this, null );
}
private static void verifyOrdinalParamLabels(Set<Integer> labels) {
if ( !isEmpty( labels ) ) {
final List<Integer> sortedLabels = new ArrayList<>( labels );
sortedLabels.sort( ComparableComparator.instance() );
int lastPosition = -1;
for ( Integer sortedPosition : sortedLabels ) {
if ( lastPosition == -1 ) {
if ( sortedPosition != 1 ) {
throw new ParameterLabelException(
String.format(
Locale.ROOT,
"Ordinal parameter labels start from '?%s' (ordinal parameters must be labelled from '?1')",
sortedPosition
)
);
}
}
else {
if ( sortedPosition != lastPosition + 1 ) {
throw new ParameterLabelException(
String.format(
Locale.ROOT,
"Gap between '?%s' and '?%s' in ordinal parameter labels [%s] (ordinal parameters must be labelled sequentially)",
lastPosition,
sortedPosition,
join( ",", sortedLabels.iterator() )
)View on GitHub (pinned to fad1729dce)
Solutions
- Renumber the ordinal labels in the query string so they start at ?1.
- Prefer named parameters (:name) so labels can never go stale.
- If many migrated queries are affected, add a startup or test-time check that parses each HQL string and validates the labels before first use.
Example fix
// before
List<Person> people = session
.createQuery("from Person p where p.age > ?2", Person.class)
.list(); // ParameterLabelException: labels must start from '?1'
// after
List<Person> people = session
.createQuery("from Person p where p.age > ?1", Person.class)
.list(); Defensive patterns
Strategy: validation
Validate before calling
static void checkOrdinalLabels(String hql) {
java.util.regex.Matcher m = java.util.regex.Pattern.compile("\\?(\\d+)").matcher(hql);
java.util.TreeSet<Integer> labels = new java.util.TreeSet<>();
while (m.find()) labels.add(Integer.parseInt(m.group(1)));
int expected = 1;
for (int label : labels) {
if (label != expected) throw new IllegalArgumentException(
"Ordinal labels must start at ?1 and be sequential; offending label ?" + label);
expected++;
}
} Try / catch
try {
em.createQuery(hql);
} catch (IllegalArgumentException e) { // ParameterLabelException extends it
// surface 'labels start from ?1' to the caller / fail the test
} Prevention
- Prefer named parameters in HQL/JPQL.
- Run a unit test that creates every application query at startup to catch label errors early.
- When deleting a predicate, renumber all remaining ordinal labels in the same edit.
When it happens
Trigger: Creating a query whose first (lowest) ordinal label is greater than 1, e.g. createQuery("... where p.age > ?2") or one starting at ?3. The exception is thrown while building ParameterMetadata, before any parameter is bound or the query executes.
Common situations: Upgrading Hibernate 5 to 6/7 where legacy queries kept arbitrary ?N numbers; deleting the first parameter from a query string and leaving later labels unshifted; copying numbered placeholders from SQL logs back into HQL.
Related errors
- Gap between '?%s' and '?%s' in ordinal parameter labels [%s]
- Function %s() has %d parameters, but %d arguments given
- Parameter %d of function '%s()' has type '%s', but argument
- No parameter labelled '?%s' in query with ordinal parameters
- No argument for ordinal parameter '?{}'
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/15bfb6329eb35996.
Report an issue: GitHub.