hibernate/hibernate-orm · error · UnsupportedOperationException

Cte root does not have an entity type. Use getReferencedPath

Error message

Cte root does not have an entity type. Use getReferencedPathSource() instead.

What it means

SqmCteRoot is the root created for "from <cteName>" after an HQL "with" clause. CTE rows are produced by a query, not mapped to an entity, so getModel() - which must return an SqmEntityDomainType - throws UnsupportedOperationException. The message points to getReferencedPathSource(), which returns the CTE's column-shaped path source. Note that SqmCteRoot.createCorrelation() returns a SqmCorrelatedDerivedRoot, propagating the same constraint to correlated usage.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/query/sqm/tree/spi/domain/SqmCteRoot.java:90

		return path;
	}

	public SqmCteStatement<T> getCte() {
		return cte;
	}

	@Override
	public <X> X accept(SemanticQueryWalker<X> walker) {
		return walker.visitRootCte( this );
	}

	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// JPA

	@Nonnull
	@Override
	public SqmEntityDomainType<T> getModel() {
		throw new UnsupportedOperationException( "Cte root does not have an entity type. Use getReferencedPathSource() instead." );
	}

	@Override
	public String getEntityName() {
		throw new UnsupportedOperationException( "Cte 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

  1. Use getReferencedPathSource() or getResolvedModel() to inspect the CTE column structure.
  2. Guard root-walking code with instanceof checks for SqmCteRoot (and SqmDerivedRoot) before calling getModel().
  3. If entity metadata is mandatory (e.g. for locking or second-level cache), query the mapped entity instead of the CTE, or register the CTE result table as an entity.
  4. For correlated subqueries over a CTE, apply the same getReferencedPathSource() pattern on the SqmCorrelatedDerivedRoot.

Example fix

// before - CTE root has no EntityType
jakarta.persistence.metamodel.EntityType<?> et =
        (jakarta.persistence.metamodel.EntityType<?>) cteRoot.getModel();

// after - inspect the CTE columns via the referenced path source
SqmPathSource<?> columns = cteRoot.getReferencedPathSource();
String cteName = columns.getPathName();
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.SqmCteRoot)
        && !(root instanceof org.hibernate.query.sqm.tree.spi.domain.SqmDerivedRoot)
        && !(root instanceof org.hibernate.query.sqm.tree.spi.domain.SqmFunctionRoot)
        && !(root instanceof org.hibernate.query.sqm.tree.spi.domain.SqmCorrelatedDerivedRoot);
}

Type guard

static boolean isCteRoot(Object node) {
    return node instanceof org.hibernate.query.sqm.tree.spi.from.SqmCteRoot<?>;
}

Try / catch

try {
    EntityType<?> t = (EntityType<?>) root.getModel();
} catch (UnsupportedOperationException e) {
    SqmPathSource<?> cteShape = ((SqmCteRoot<?>) root).getReferencedPathSource();
    // drive column handling from the CTE path source
}

Prevention

When it happens

Trigger: HQL "with t as (select ...) select x from t x" plus Java code calling root.getModel() on the CTE root (common in Specifications, entity-graph appliers, or logging layers that walk query roots); Criteria-style APIs that resolve EntityType from every root; correlating a CTE root into a subquery and then asking for its model.

Common situations: Adopting Hibernate 6.6/7 CTE-in-HQL features in codebases where generic root-processing assumed entity roots; recursive-CTE queries for tree traversals hitting framework code that expects entities; migrating Blaze-Persistence CTE queries (which use @CTE entities) to native HQL CTEs, where getModel() no longer applies.

Related errors


AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22). Data as JSON: /api/errors/4965992c7ec2093f. Report an issue: GitHub.