{"record":{"id":"74fa161d71f3e40b","repo":"hibernate/hibernate-orm","slug":"derived-root-does-not-have-an-entity-type-use-get","errorCode":null,"errorMessage":"Derived root does not have an entity type. Use getReferencedPathSource() instead.","messagePattern":"Derived 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/SqmDerivedRoot.java","lineNumber":94,"sourceCode":"\t@Nonnull\n\t@Override\n\tpublic SqmSubQuery<T> getQueryPart() {\n\t\treturn subQuery;\n\t}\n\n\t@Override\n\tpublic <X> X accept(SemanticQueryWalker<X> walker) {\n\t\treturn walker.visitRootDerived( this );\n\t}\n\n\t// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\t// JPA\n\n\t@Nonnull\n\t@Override\n\tpublic SqmEntityDomainType<T> getModel() {\n\t\t// Or should we throw an exception instead?\n\t\tthrow new UnsupportedOperationException( \"Derived 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( \"Derived 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":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/spi/domain/SqmDerivedRoot.java#L76-L112","documentation":"SqmDerivedRoot is the root created for HQL \"from (select ...) alias\" (derived table in the from clause). Its rows come from an inner subquery, so the JPA Root contract getModel() cannot return an EntityType and Hibernate throws UnsupportedOperationException (the source even carries a comment debating whether to throw - it does). getReferencedPathSource() exposes the subquery's select-shape instead.","triggerScenarios":"HQL \"select d.x from (select e.id as x from Employee e) d\" combined with Java code that calls root.getModel() on the derived root; criteria/metamodel frameworks resolving an EntityType from every root; correlating the derived root (createCorrelation()) and calling getModel() on the resulting SqmCorrelatedDerivedRoot.","commonSituations":"Reporting queries refactored to derived tables for paging/deduplication while generic root code still expects entities; Hibernate 6.6+/7 making \"from (subquery)\" a supported pattern that now flows into previously entity-only code paths; migration from Blaze-Persistence or native SQL subselect-from queries.","solutions":["Call getReferencedPathSource() (or getResolvedModel()) to inspect the derived row type.","Type-guard generic code: skip getModel() for SqmDerivedRoot and SqmCteRoot instances.","Select from the mapped entity directly when EntityType-driven features (locking, caching, metamodel queries) are needed.","Where feasible, move the derived projection into a subquery in the where clause so the outer query keeps entity roots."],"exampleFix":"// before - derived root has no entity model\nEntityType<?> et = (EntityType<?>) derivedRoot.getModel();\n\n// after - use the referenced path source of the derived table\nSqmPathSource<?> shape = derivedRoot.getReferencedPathSource();\nClass<?> rowType = shape.getJavaType();","handlingStrategy":"type-guard","validationCode":"static boolean hasEntityType(jakarta.persistence.criteria.Root<?> root) {\n    return !(root instanceof org.hibernate.query.sqm.tree.spi.domain.SqmDerivedRoot)\n        && !(root instanceof org.hibernate.query.sqm.tree.spi.domain.SqmCteRoot)\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 isDerivedRoot(Object node) {\n    return node instanceof org.hibernate.query.sqm.tree.spi.domain.SqmDerivedRoot;\n}","tryCatchPattern":"try {\n    EntityType<?> et = (EntityType<?>) root.getModel();\n} catch (UnsupportedOperationException e) {\n    SqmPathSource<?> shape = ((SqmDerivedRoot<?>) root).getReferencedPathSource();\n    Class<?> rowType = shape.getJavaType();\n}","preventionTips":["Call getResolvedModel()/getReferencedPathSource() in generic code instead of getModel().","When introducing 'from (select ...)' queries, audit framework hooks that assume entity roots.","Keep entity-dependent operations (locking, cache) on entity-root queries only."],"tags":["hibernate","hql","sqm","derived-root","subquery"],"backgroundTag":"derived-root-no-entity-type","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}