hibernate/hibernate-orm · error · UnsupportedOperationException
Derived roots can not be treated
Error message
Derived roots can not be treated
What it means
SqmDerivedRoot.treatAs throws UnsupportedOperationException: TREAT requires an entity inheritance hierarchy, but a derived root denotes subquery rows with no persistent type hierarchy, so downcasting it is meaningless. This is the derived-root counterpart of the basic-path treat failures. The exception is thrown while the SQM tree is built, before SQL rendering.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/query/sqm/tree/spi/domain/SqmDerivedRoot.java:116
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 );
}
@Override
@Nonnull
public <S extends T> SqmTreatedFrom<T, T, S> treatAs(@Nonnull EntityDomainType<S> treatTarget, @Nullable String alias, boolean fetch) {
throw new UnsupportedOperationException( "Derived roots can not be treated" );
}
@Override
public boolean deepEquals(SqmFrom<?, ?> object) {
return super.deepEquals( object )
&& subQuery.equals( ((SqmDerivedRoot<?>) object).subQuery );
}
@Override
public boolean isDeepCompatible(SqmFrom<?, ?> object) {
return super.isDeepCompatible( object )
&& subQuery.isCompatible( ((SqmDerivedRoot<?>) object).subQuery );
}
}
View on GitHub (pinned to fad1729dce)
Solutions
- Apply TREAT inside the inner subquery before deriving: "from (select treat(e as Manager) m from Employee e) t" select m.bonus from t.
- Or treat the entity root directly in an ordinary query and push filtering into a where clause instead of a derived table.
- If only subclass rows matter, filter with a type() predicate in the inner select: "select e from Employee e where type(e) = Manager".
- Avoid treatAs on any root that is not a plain SqmRoot/SqmEntityJoin.
Example fix
// before - derived root cannot be treated "select treat(t as Manager).bonus from (select e from Employee e) t" // after - treat inside the derived subquery first "select t.bonus from (select treat(e as Manager) as m from Employee e where type(e) = Manager) t"
Defensive patterns
Strategy: type-guard
Validate before calling
// Only emit TREAT when the treated node is a plain entity root/join
static boolean treatableRoot(Object node) {
return node instanceof org.hibernate.query.sqm.tree.spi.from.SqmRoot
|| node instanceof org.hibernate.query.sqm.tree.spi.from.SqmEntityJoin
|| node instanceof org.hibernate.query.sqm.tree.spi.from.SqmCrossJoin;
// note: SqmDerivedRoot, SqmCteRoot, SqmCorrelatedDerivedRoot throw on treatAs
} Type guard
static boolean isDerivedRoot(Object node) {
return node instanceof org.hibernate.query.sqm.tree.spi.domain.SqmDerivedRoot;
} Try / catch
try {
root.treatAs(target, alias, fetch);
} catch (UnsupportedOperationException e) {
throw new IllegalArgumentException("TREAT is not supported on derived roots; move treat into the inner subquery", e);
} Prevention
- When refactoring entity queries into from-subquery form, move TREAT inside the subquery.
- Use type(e) = Subclass predicates in the inner select as an alternative to treat.
- Static-check for treatAs( on roots whose query contains 'from (' during code review.
When it happens
Trigger: HQL "select treat(t as Manager).bonus from (select e from Employee e) t"; criteria code calling derivedRoot.treatAs(Manager.class) on a root created for a from-subquery; copy of entity-root treat patterns applied to derived roots.
Common situations: Queries rewritten over derived tables (for window functions, row limiting) that kept TREAT from the original entity query; migration from Blaze-Persistence where treating subselect aliases behaved differently; assumption that "from (select e from Employee e)" preserves treatability of e.
Related errors
- Derived root does not have an entity type. Use getReferenced
- Cannot apply TREAT operator to discriminator path
- Non-aggregate composite paths cannot be TREAT-ed
- Basic-value cannot be treated (downcast)
- Correlated derived root does not have an entity type. Use ge
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/46002146e6de2a96.
Report an issue: GitHub.