hibernate/hibernate-orm · error · UnsupportedOperationException
Correlated derived root does not have an entity type. Use…
Error message
Correlated derived root does not have an entity type. Use getReferencedPathSource() instead.
What it means
SqmCorrelatedDerivedRoot wraps a subquery root that was correlated into an inner query and whose outer referent is a derived root (a "from (select ...)" group, often created via SqmCteRoot.createCorrelation() or correlating a derived root inside a subquery). Such a root denotes query-derived rows, not a mapped entity, so the JPA Root contract getModel() (returning an EntityType) cannot be honored; Hibernate throws UnsupportedOperationException and the message tells you to use getReferencedPathSource() to inspect the row type instead.
Solutions
- Use getReferencedPathSource() (or getResolvedModel(), which delegates to it) to obtain the SqmPathSource describing the derived rows.
- Guard generic root-handling code: skip or special-case roots that are SqmDerivedRoot, SqmCteRoot, or SqmCorrelatedDerivedRoot before calling getModel().
- When an EntityType is genuinely required, query the underlying mapped entity directly instead of a derived table.
- Catch UnsupportedOperationException as a last resort in framework code and fall back to getJavaType() metadata.
Example fix
// before - breaks when the correlated root wraps a derived/CTE root
EntityType<?> t = (EntityType<?>) root.getModel();
String name = t.getName();
// after - ask for the referenced path source, which always exists
String name = ((org.hibernate.query.sqm.tree.spi.domain.SqmPath<?>) root)
.getReferencedPathSource().getPathName(); Defensive patterns
Strategy: type-guard
Validate before calling
// In generic root walkers, probe for entity-backed roots before using getModel()
static boolean hasEntityType(jakarta.persistence.criteria.Root<?> root) {
return !(root instanceof org.hibernate.query.sqm.tree.spi.domain.SqmCorrelatedDerivedRoot)
&& !(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);
} Type guard
static boolean isEntityBackedRoot(Object sqmRoot) {
return sqmRoot instanceof org.hibernate.query.sqm.tree.spi.from.SqmRoot
|| sqmRoot instanceof org.hibernate.query.sqm.tree.spi.from.SqmCrossJoin
|| sqmRoot instanceof org.hibernate.query.sqm.tree.spi.from.SqmEntityJoin;
} Try / catch
try {
return root.getModel();
} catch (UnsupportedOperationException e) {
// derived/CTE/correlated-derived roots: no EntityType available
return null; // caller falls back to getReferencedPathSource() / getJavaType()
} Prevention
- Never call getModel() unconditionally on roots received from arbitrary queries.
- Prefer getResolvedModel()/getReferencedPathSource() which works for all root kinds.
- Add CTE and derived-table queries to the corpus your framework tests against.
- Treat 'UnsupportedOperationException from getModel' as a missing-type-check code smell, not a runtime hazard to swallow.
When it happens
Trigger: HQL with a derived table correlated into a subquery, e.g. "select e from Employee e where exists (select 1 from (select ...) d where d.x = e.x)" combined with Java code that calls root.getModel() on the subquery root; Criteria code doing subquery.correlate(derivedRoot).getModel(); generic framework code (Specifications, auditors, entity-graph appliers) that unconditionally calls getModel() on every root of every query.
Common situations: Spring Data JPA or in-house specification layers that resolve root.getModel().getName() for aliasing or logging on arbitrary queries; migrating queries from entity roots to CTE/derived-table style (Hibernate 6.6+/7 improved support) and legacy root-processing code breaking; correlation of a CTE root (SqmCteRoot.createCorrelation returns SqmCorrelatedDerivedRoot).
Related errors
- Can't set alias on a correlated root
- Correlated derived root does not have an entity type. Use…
- Not correlated
- Cannot correlate from node
- Derived root does not have an entity type. Use…
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/e91a1d70ff85b664.
Report an issue: GitHub.
Appendix: source
Thrown at hibernate-core/src/main/java/org/hibernate/query/sqm/tree/spi/domain/SqmCorrelatedDerivedRoot.java:54
final var existing = context.getCopy( this );
if ( existing != null ) {
return existing;
}
final var path = context.registerCopy(
this,
new SqmCorrelatedDerivedRoot<>( getCorrelationParent().copy( context ) )
);
copyTo( path, context );
return path;
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// JPA
@Nonnull
@Override
public SqmEntityDomainType<T> getModel() {
throw new UnsupportedOperationException( "Correlated derived root does not have an entity type. Use getReferencedPathSource() instead." );
}
@Override
public String getEntityName() {
throw new UnsupportedOperationException( "Correlated derived root does not have an entity type. Use getReferencedPathSource() instead." );
}
@Override
public SqmPathSource<T> getResolvedModel() {
return getReferencedPathSource();
}
}
View on GitHub (pinned to fad1729dce)