hibernate/hibernate-orm · error · TreatException
Root path treats can not be fetched - " + getNavigablePath()
Error message
Root path treats can not be fetched - " + getNavigablePath().getFullPath()
What it means
SqmRoot.treatAs(EntityDomainType, alias, fetch) throws TreatException when fetch=true. A root treat is a type-narrowing expression, not a fetch graph element: SQL TREAT does not fetch anything itself, and Hibernate cannot generate fetch joins for a virtual treated root on top of the existing root row. Root treats are only valid as unaliased, unfetched path sources; fetching must be expressed as explicit fetch joins.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/query/sqm/tree/spi/from/SqmRoot.java:255
@Nonnull
public <S extends E> SqmTreatedFrom<E,E,S> treatAs(@Nonnull EntityDomainType<S> treatTarget, @Nullable String alias) {
return treatAs( treatTarget, alias, false );
}
@Override
@Nonnull
public <S extends E> SqmTreatedFrom<E,E,S> treatAs(@Nonnull Class<S> treatJavaType, @Nullable String alias, boolean fetch) {
return treatAs( nodeBuilder().getDomainModel().entity( treatJavaType ), alias, fetch );
}
@Override
@Nonnull
public <S extends E> SqmTreatedFrom<E,E,S> treatAs(@Nonnull EntityDomainType<S> treatTarget, @Nullable String alias, boolean fetch) {
if ( alias != null ) {
throw new TreatException( "Root path treats can not be aliased - " + getNavigablePath().getFullPath() );
}
if ( fetch ) {
throw new TreatException( "Root path treats can not be fetched - " + getNavigablePath().getFullPath() );
}
final var treat = findTreat( treatTarget, null );
if ( treat == null ) {
final var treatedRoot = new SqmTreatedRoot<>( this, (SqmEntityDomainType<S>) treatTarget );
@SuppressWarnings("unchecked")
final var typedTreat = (SqmTreatedFrom<E, E, S>) treatedRoot;
return addTreat( typedTreat );
}
return treat;
}
}
View on GitHub (pinned to fad1729dce)
Solutions
- Use `root.treatAs( Sub.class )` without fetch, and add explicit fetch joins on the treated path: `join fetch p.subAttr`
- Move the fetch to an association join and treat that join: `join p.related r fetch` + `treat(r as Sub)`
- Select the subtype attributes you need instead of fetching them
- Restructure the query as a subtype-targeted query (`from SpecialPerson`) when you only want that subtype with its associations
Example fix
// before (HQL: root treat + fetch)
List<Person> l = session.createQuery("from Person p join fetch treat(p as SpecialPerson).bonus", Person.class).list();
// after
List<SpecialPerson> l = session.createQuery("from SpecialPerson s join fetch s.bonus", SpecialPerson.class).list(); Defensive patterns
Strategy: validation
Validate before calling
boolean fetched = false; // root treats can never be fetched root.treatAs( Sub.class, null, fetched ); // or simply: root.treatAs( Sub.class );
Prevention
- Never combine JOIN FETCH with TREAT at the root level
- Express fetching through explicit fetch joins on associations
- Query the concrete subtype directly when its associations must be fetched
When it happens
Trigger: Criteria: `root.treatAs( Sub.class, null, true )` — the three-arg overload with fetched=true. HQL constructs that translate to a fetched root treat, e.g. `join fetch treat(p as Sub).attr` on a root, which sets the fetched flag on SqmRoot.treatAs. Generic code that always passes fetched=true.
Common situations: Trying to combine TREAT with JOIN FETCH at the root level (`from Person p join fetch treat(p as Sub).specialAttr`); building generic fetch-graph resolvers that mark every treated path as fetched; upgrading from older Hibernate versions where this pattern was silently accepted or failed later.
Related errors
- Root path treats can not be aliased - " + getNavigablePath()
- CTE joins can not be treated
- Derived joins can not be treated
- Entity join treats can not be aliased
- Function joins can not be treated
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/df5a26de3a102edc.
Report an issue: GitHub.