hibernate/hibernate-orm · error · UnsupportedOperationException
Function root does not have an entity type. Use getReference
Error message
Function root does not have an entity type. Use getReferencedPathSource() instead.
What it means
SqmFunctionRoot is a query root derived from a function call (Hibernate 7 function roots / set-returning functions in the FROM clause). It has no entity metamodel identity, so the JPA Root.getModel() contract, which promises an SqmEntityDomainType, throws UnsupportedOperationException; the message points you to getReferencedPathSource() (also exposed as getResolvedModel()) for the actual path source.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/query/sqm/tree/spi/domain/SqmFunctionRoot.java:99
final SqmPathSource<?> pathSource =
function.getType().getSubPathSource( CollectionPart.Nature.INDEX.getName() );
//noinspection unchecked
final SqmPathSource<Long> indexPathSource = (SqmPathSource<Long>) pathSource;
return resolvePath( indexPathSource.getPathName(), indexPathSource );
}
@Override
public <X> X accept(SemanticQueryWalker<X> walker) {
return walker.visitRootFunction( this );
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// JPA
@Nonnull
@Override
public SqmEntityDomainType<E> getModel() {
throw new UnsupportedOperationException( "Function root does not have an entity type. Use getReferencedPathSource() instead." );
}
@Override
public String getEntityName() {
throw new UnsupportedOperationException( "Function root does not have an entity type. Use getReferencedPathSource() instead." );
}
@Override
public SqmPathSource<E> getResolvedModel() {
return getReferencedPathSource();
}
@Override
@Nonnull
public SqmCorrelatedRoot<E> createCorrelation() {
throw new UnsupportedOperationException();
}
View on GitHub (pinned to fad1729dce)
Solutions
- Replace getModel() with getResolvedModel()/getReferencedPathSource(), which works for both entity and function roots
- Guard generic code: if (root instanceof SqmFunctionRoot) skip entity-specific handling such as getModel()/getEntityName()
- If you truly need the entity type, obtain it from the function's return type (referenced path source's path type) instead
Example fix
// before
SqmRoot<?> root = ...; // may be a function root
String name = root.getModel().getHibernateEntityName(); // throws on SqmFunctionRoot
// after
if (root instanceof SqmFunctionRoot<?> fr) {
SqmPathSource<?> src = fr.getReferencedPathSource(); // no entity metamodel exists
} else {
String name2 = root.getModel().getHibernateEntityName();
} Defensive patterns
Strategy: type-guard
Type guard
static SqmPathSource<?> referencedSource(SqmRoot<?> root) {
// works for entity roots and function roots alike
return root instanceof SqmFunctionRoot<?> fr
? fr.getReferencedPathSource()
: root.getModel();
} Try / catch
try {
SqmEntityDomainType<?> t = root.getModel();
} catch (UnsupportedOperationException e) {
// function root has no entity type: fall back to getReferencedPathSource()
SqmPathSource<?> src = ((SqmFunctionRoot<?>) root).getReferencedPathSource();
} Prevention
- Prefer getResolvedModel()/getReferencedPathSource() over getModel() in generic root handling
- Branch on 'root instanceof SqmFunctionRoot' before JPA Root contract calls
- Do not assume every SqmRoot has an entity name in Hibernate 7 codebases using function roots
- Cover function-root queries in tests for custom criteria utilities
When it happens
Trigger: Calling getModel() on a root created for a function in the FROM clause, e.g. 'from unnest(...) u' / json_table roots, through generic criteria-inspection code, query transformers, or libraries that assume every SqmRoot is entity-backed.
Common situations: Spring Data JPA / Blaze-Persistence / reporting tooling calling getModel() or getEntityName() on arbitrary roots; custom query copy/rewrite utilities iterating over query roots; adoption of Hibernate 7 function roots in codebases with generic criteria infrastructure.
Related errors
- MappedSuperclassType cannot be used to create an SqmPath - t
- LHS cannot be null for a sub-navigable reference - {}
- Not correlated
- Could not interpret attribute '%s' of basic-valued path '%s'
- Boolean expression does not support max()
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/bc9a15208e4d5b7e.
Report an issue: GitHub.