{"record":{"id":"4965992c7ec2093f","repo":"hibernate/hibernate-orm","slug":"cte-root-does-not-have-an-entity-type-use-getrefe","errorCode":null,"errorMessage":"Cte root does not have an entity type. Use getReferencedPathSource() instead.","messagePattern":"Cte root does not have an entity type\\. Use getReferencedPathSource\\(\\) instead\\.","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/query/sqm/tree/spi/domain/SqmCteRoot.java","lineNumber":90,"sourceCode":"\t\treturn path;\n\t}\n\n\tpublic SqmCteStatement<T> getCte() {\n\t\treturn cte;\n\t}\n\n\t@Override\n\tpublic <X> X accept(SemanticQueryWalker<X> walker) {\n\t\treturn walker.visitRootCte( this );\n\t}\n\n\t// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\t// JPA\n\n\t@Nonnull\n\t@Override\n\tpublic SqmEntityDomainType<T> getModel() {\n\t\tthrow new UnsupportedOperationException( \"Cte root does not have an entity type. Use getReferencedPathSource() instead.\" );\n\t}\n\n\t@Override\n\tpublic String getEntityName() {\n\t\tthrow new UnsupportedOperationException( \"Cte root does not have an entity type. Use getReferencedPathSource() instead.\" );\n\t}\n\n\t@Override\n\tpublic SqmPathSource<T> getResolvedModel() {\n\t\treturn getReferencedPathSource();\n\t}\n\n\t@Override\n\t@Nonnull\n\tpublic SqmCorrelatedRoot<T> createCorrelation() {\n\t\treturn new SqmCorrelatedDerivedRoot<>( this );\n\t}\n","sourceCodeStart":72,"sourceCodeEnd":108,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/spi/domain/SqmCteRoot.java#L72-L108","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Use getReferencedPathSource() or getResolvedModel() to inspect the CTE column structure.","Guard root-walking code with instanceof checks for SqmCteRoot (and SqmDerivedRoot) before calling getModel().","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.","For correlated subqueries over a CTE, apply the same getReferencedPathSource() pattern on the SqmCorrelatedDerivedRoot."],"exampleFix":"// before - CTE root has no EntityType\njakarta.persistence.metamodel.EntityType<?> et =\n        (jakarta.persistence.metamodel.EntityType<?>) cteRoot.getModel();\n\n// after - inspect the CTE columns via the referenced path source\nSqmPathSource<?> columns = cteRoot.getReferencedPathSource();\nString cteName = columns.getPathName();","handlingStrategy":"type-guard","validationCode":"static boolean hasEntityType(jakarta.persistence.criteria.Root<?> root) {\n    return !(root instanceof org.hibernate.query.sqm.tree.spi.domain.SqmCteRoot)\n        && !(root instanceof org.hibernate.query.sqm.tree.spi.domain.SqmDerivedRoot)\n        && !(root instanceof org.hibernate.query.sqm.tree.spi.domain.SqmFunctionRoot)\n        && !(root instanceof org.hibernate.query.sqm.tree.spi.domain.SqmCorrelatedDerivedRoot);\n}","typeGuard":"static boolean isCteRoot(Object node) {\n    return node instanceof org.hibernate.query.sqm.tree.spi.from.SqmCteRoot<?>;\n}","tryCatchPattern":"try {\n    EntityType<?> t = (EntityType<?>) root.getModel();\n} catch (UnsupportedOperationException e) {\n    SqmPathSource<?> cteShape = ((SqmCteRoot<?>) root).getReferencedPathSource();\n    // drive column handling from the CTE path source\n}","preventionTips":["Use getResolvedModel() instead of getModel() in code that may see CTE roots.","Register CTE-containing queries in framework test corpora when adopting HQL CTEs.","When porting from Blaze-Persistence @CTE entities, replace entity-name lookups with CTE names."],"tags":["hibernate","hql","sqm","cte","criteria-api"],"backgroundTag":"cte-root-no-entity-type","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}