hibernate/hibernate-orm · error · UnsupportedOperationException
Derived root does not have an entity type. Use getReferenced
Error message
Derived root does not have an entity type. Use getReferencedPathSource() instead.
What it means
SqmDerivedRoot is the root created for HQL "from (select ...) alias" (derived table in the from clause). Its rows come from an inner subquery, so the JPA Root contract getModel() cannot return an EntityType and Hibernate throws UnsupportedOperationException (the source even carries a comment debating whether to throw - it does). getReferencedPathSource() exposes the subquery's select-shape instead.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/query/sqm/tree/spi/domain/SqmDerivedRoot.java:94
@Nonnull
@Override
public SqmSubQuery<T> getQueryPart() {
return subQuery;
}
@Override
public <X> X accept(SemanticQueryWalker<X> walker) {
return walker.visitRootDerived( this );
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// JPA
@Nonnull
@Override
public SqmEntityDomainType<T> getModel() {
// Or should we throw an exception instead?
throw new UnsupportedOperationException( "Derived root does not have an entity type. Use getReferencedPathSource() instead." );
}
@Override
public String getEntityName() {
throw new UnsupportedOperationException( "Derived root does not have an entity type. Use getReferencedPathSource() instead." );
}
@Override
public SqmPathSource<T> getResolvedModel() {
return getReferencedPathSource();
}
@Override
@Nonnull
public SqmCorrelatedRoot<T> createCorrelation() {
return new SqmCorrelatedDerivedRoot<>( this );
}
View on GitHub (pinned to fad1729dce)
Solutions
- Call getReferencedPathSource() (or getResolvedModel()) to inspect the derived row type.
- Type-guard generic code: skip getModel() for SqmDerivedRoot and SqmCteRoot instances.
- Select from the mapped entity directly when EntityType-driven features (locking, caching, metamodel queries) are needed.
- Where feasible, move the derived projection into a subquery in the where clause so the outer query keeps entity roots.
Example fix
// before - derived root has no entity model EntityType<?> et = (EntityType<?>) derivedRoot.getModel(); // after - use the referenced path source of the derived table SqmPathSource<?> shape = derivedRoot.getReferencedPathSource(); Class<?> rowType = shape.getJavaType();
Defensive patterns
Strategy: type-guard
Validate before calling
static boolean hasEntityType(jakarta.persistence.criteria.Root<?> root) {
return !(root instanceof org.hibernate.query.sqm.tree.spi.domain.SqmDerivedRoot)
&& !(root instanceof org.hibernate.query.sqm.tree.spi.domain.SqmCteRoot)
&& !(root instanceof org.hibernate.query.sqm.tree.spi.domain.SqmFunctionRoot)
&& !(root instanceof org.hibernate.query.sqm.tree.spi.domain.SqmCorrelatedDerivedRoot);
} Type guard
static boolean isDerivedRoot(Object node) {
return node instanceof org.hibernate.query.sqm.tree.spi.domain.SqmDerivedRoot;
} Try / catch
try {
EntityType<?> et = (EntityType<?>) root.getModel();
} catch (UnsupportedOperationException e) {
SqmPathSource<?> shape = ((SqmDerivedRoot<?>) root).getReferencedPathSource();
Class<?> rowType = shape.getJavaType();
} Prevention
- Call getResolvedModel()/getReferencedPathSource() in generic code instead of getModel().
- When introducing 'from (select ...)' queries, audit framework hooks that assume entity roots.
- Keep entity-dependent operations (locking, cache) on entity-root queries only.
When it happens
Trigger: HQL "select d.x from (select e.id as x from Employee e) d" combined with Java code that calls root.getModel() on the derived root; criteria/metamodel frameworks resolving an EntityType from every root; correlating the derived root (createCorrelation()) and calling getModel() on the resulting SqmCorrelatedDerivedRoot.
Common situations: Reporting queries refactored to derived tables for paging/deduplication while generic root code still expects entities; Hibernate 6.6+/7 making "from (subquery)" a supported pattern that now flows into previously entity-only code paths; migration from Blaze-Persistence or native SQL subselect-from queries.
Related errors
- Derived roots can not be treated
- Correlated derived root does not have an entity type. Use ge
- Entity discriminator cannot be de-referenced
- Entity discriminator cannot be de-referenced
- Could not resolve attribute '%s' of '%s' due to the attribut
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/74fa161d71f3e40b.
Report an issue: GitHub.