hibernate/hibernate-orm · error · SemanticException
Index operator applied to non-plural path '${getNavigablePat
Error message
Index operator applied to non-plural path '${getNavigablePath()}' What it means
In HQL, `path[selector]` (indexed access) is dispatched by SemanticQueryBuilder.visitIndexedPathAccessFragment (SemanticQueryBuilder.java:5840) to SqmPath.resolveIndexedAccess. Only plural paths - list/map attributes via SqmPluralValuedSimplePath, plus function paths - implement it; the SqmPath default throws SemanticException('Index operator applied to non-plural path \'<navigablePath>\'') naming the exact offending path. It means the [] operator was applied to a singular attribute (basic value, embeddable, or single-valued association).
Source
Thrown at hibernate-core/src/main/java/org/hibernate/query/sqm/tree/spi/domain/SqmPath.java:144
final var lhs = getLhs();
if ( lhs != null ) {
return lhs.findRoot();
}
throw new ParsingException( "Could not find root" );
}
SqmPath<?> resolvePathPart(
String name,
boolean isTerminal,
SqmCreationState creationState);
@Override
default SqmPath<?> resolveIndexedAccess(
SqmExpression<?> selector,
boolean isTerminal,
SqmCreationState creationState) {
throw new SemanticException( "Index operator applied to non-plural path '" + getNavigablePath() + "'" );
}
/**
* Get this path's actual resolved model, i.e. the concrete type for generic attributes.
*/
SqmPathSource<T> getResolvedModel();
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Covariant overrides
@Nonnull
@Override
<Y> SqmPath<Y> get(@Nonnull SingularAttribute<? super T, Y> attribute);
@Nonnull
@Override
<E, C extends Collection<E>> SqmPluralPath<C,E> get(@Nonnull PluralAttribute<? super T, C, E> collection);
View on GitHub (pinned to fad1729dce)
Solutions
- Use [] only on List- or Map-valued plural attributes (@ElementCollection, @OneToMany/@ManyToMany)
- For strings, use substring()/like instead of name[1]
- Check the attribute spelling - the intended plural attribute may have a different name
- Map the data as a real collection (e.g. @ElementCollection List) or use JSON functions if the column holds JSON
Example fix
// before - name is a singular String attribute select p from Person p where p.name[1] = 'B' // after - use string functions on singular attributes select p from Person p where substring( p.name, 1, 1 ) = 'B'
Defensive patterns
Strategy: validation
Validate before calling
import jakarta.persistence.metamodel.*;
Attribute<?, ?> attr = entityManager.getMetamodel()
.entity( Person.class )
.getAttribute( attributeName );
if ( !(attr instanceof ListAttribute || attr instanceof MapAttribute) ) {
throw new IllegalArgumentException(
"Cannot apply [] to '" + attributeName + "': not a List/Map attribute" );
}
// safe to emit: path[...] or path[index] Type guard
static boolean isIndexable(Attribute<?, ?> attribute) {
return attribute instanceof jakarta.persistence.metamodel.ListAttribute<?, ?>
|| attribute instanceof jakarta.persistence.metamodel.MapAttribute<?, ?, ?>;
} Try / catch
try {
return session.createQuery( hql, Person.class ).list();
} catch ( org.hibernate.query.SemanticException e ) {
if ( e.getMessage() != null && e.getMessage().startsWith( "Index operator applied to non-plural path" ) ) {
throw new IllegalArgumentException( "HQL uses [] on a singular attribute: " + hql, e );
}
throw e;
} Prevention
- Reserve the [] operator for List- and Map-valued attributes
- Validate dynamically built HQL fragments against the metamodel before execution
- Use substring()/like for string character access
- Keep HQL in sync when attributes change between singular and plural
- Prefer criteria API for dynamic paths - type errors surface at compile time
When it happens
Trigger: Any HQL path expression with an index on a non-plural attribute: `where p.name[1] = 'B'` (String attribute), `select e.address[0]` (embeddable), `p.contact[0]` (singular association); also typos where a similarly named singular attribute resolves instead of the intended List/Map attribute.
Common situations: Assuming HQL supports Java-style String/array indexing; migrating native SQL with array subscripts to HQL; an attribute refactored from List<X> to X (or renamed) leaving stale HQL; JSON-style access attempts on basic columns.
Related errors
- Index access is only supported for basic plural and string t
- Attribute '{attribute}' is not joinable
- NATIVE is not a legal field for extract()
- Inverse distribution function '%s' must specify 'WITHIN GROU
- Entity discriminator cannot be de-referenced
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/027422377a6f764f.
Report an issue: GitHub.