{"record":{"id":"b53fe69f7175351a","repo":"hibernate/hibernate-orm","slug":"from-subquery","errorCode":"FROM_SUBQUERY","errorMessage":"The JPA specification does not support subqueries in the from clause. Please disable the JPA query compliance if you want to use this feature.","messagePattern":"The JPA specification does not support subqueries in the from clause\\. Please disable the JPA query compliance if you want to use this feature\\.","errorType":"exception","errorClass":"StrictJpaComplianceViolation","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/query/hql/internal/SemanticQueryBuilder.java","lineNumber":2205,"sourceCode":"\n\t@Override\n\tpublic SqmCteStatement<?> findCteStatement(String name) {\n\t\tif ( currentPotentialRecursiveCte != null && name.equals( currentPotentialRecursiveCte.getName() ) ) {\n\t\t\treturn (SqmCteStatement<?>) currentPotentialRecursiveCte;\n\t\t}\n\t\treturn processingStateStack.findCurrentFirstWithParameter( name, SemanticQueryBuilder::matchCteStatement );\n\t}\n\n\tprivate static SqmCteStatement<?> matchCteStatement(SqmCreationProcessingState state, String n) {\n\t\treturn state.getProcessingQuery() instanceof SqmCteContainer container\n\t\t\t\t? container.getCteStatement( n )\n\t\t\t\t: null;\n\t}\n\n\t@Override\n\tpublic SqmRoot<?> visitRootSubquery(HqlParser.RootSubqueryContext ctx) {\n\t\tif ( getCreationOptions().useStrictJpaCompliance() ) {\n\t\t\tthrow new StrictJpaComplianceViolation(\n\t\t\t\t\t\"The JPA specification does not support subqueries in the from clause. \" +\n\t\t\t\t\t\t\t\"Please disable the JPA query compliance if you want to use this feature.\",\n\t\t\t\t\tStrictJpaComplianceViolation.Type.FROM_SUBQUERY\n\t\t\t);\n\t\t}\n\n\t\tfinal var subQuery = (SqmSubQuery<?>) ctx.subquery().accept( this );\n\t\tfinal String alias = extractAlias( ctx.variable() );\n\t\tfinal var sqmRoot = new SqmDerivedRoot<>( subQuery, alias );\n\t\tprocessingStateStack.getCurrent().getPathRegistry().register( sqmRoot );\n\t\treturn sqmRoot;\n\t}\n\n\t@Override\n\tpublic SqmRoot<?> visitRootFunction(HqlParser.RootFunctionContext ctx) {\n\t\tif ( getCreationOptions().useStrictJpaCompliance() ) {\n\t\t\tthrow new StrictJpaComplianceViolation(\n\t\t\t\t\t\"The JPA specification does not support functions in the from clause. \" +","sourceCodeStart":2187,"sourceCodeEnd":2223,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/query/hql/internal/SemanticQueryBuilder.java#L2187-L2223","documentation":"visitRootSubquery builds a derived root (a subquery in the from clause, e.g. 'from (select ...) s') and first checks strict JPQL query compliance. The JPA specification does not define from-clause subqueries, so with 'hibernate.jpa.compliance.query=true' the query is rejected (StrictJpaComplianceViolation.Type.FROM_SUBQUERY) with a hint to disable the flag.","triggerScenarios":"'select s.x from (select id, x from Employee) s' executed while hibernate.jpa.compliance.query (or global hibernate.jpa.compliance) is true; Spring setups where 'spring.jpa.properties.hibernate.jpa.compliance=true' was inherited.","commonSituations":"Turning on JPA compliance for certification or to catch vendor-specific usage, then hitting it on derived-table-style queries; migrating JPQL written for Hibernate extensions into a compliance-strict deployment.","solutions":["Disable the query compliance flag: 'hibernate.jpa.compliance.query=false'","Rewrite the query as a flat query with the subquery moved to a where-clause subquery or a plain join","Map the derived table as an entity backed by @Subselect, or use a native query for this read"],"exampleFix":"# before\nhibernate.jpa.compliance.query=true\nselect s.dept from (select distinct e.dept from Employee e) s\n\n# after\nhibernate.jpa.compliance.query=false","handlingStrategy":"fallback","validationCode":"static boolean strictQueryCompliance(EntityManagerFactory emf) {\n    Object v = emf.getProperties().get(\"hibernate.jpa.compliance.query\");\n    if (v == null) v = emf.getProperties().get(\"hibernate.jpa.compliance\");\n    return v != null && Boolean.parseBoolean(v.toString());\n}\n\nstatic boolean usesFromSubquery(String hql) {\n    return java.util.regex.Pattern.compile(\"\\\\bfrom\\\\s*\\\\(\", java.util.regex.Pattern.CASE_INSENSITIVE).matcher(hql).find();\n}\n\nif (strictQueryCompliance(emf) && usesFromSubquery(hql)) { /* use the flat rewrite */ }","typeGuard":"static boolean isFromSubqueryViolation(Throwable t) {\n    return t instanceof org.hibernate.query.sqm.StrictJpaComplianceViolation\n            && ((org.hibernate.query.sqm.StrictJpaComplianceViolation) t).getType() == org.hibernate.query.sqm.StrictJpaComplianceViolation.Type.FROM_SUBQUERY;\n}","tryCatchPattern":"try {\n    return em.createQuery(derivedRootHql, Tuple.class).getResultList();   // from (select ...) s\n} catch (org.hibernate.query.sqm.StrictJpaComplianceViolation e) {\n    return em.createQuery(flatJpqlRewrite, Tuple.class).getResultList(); // equivalent flat JPQL\n}","preventionTips":["Decide up front whether the deployment allows HQL extensions; pin 'hibernate.jpa.compliance.query' accordingly","Prefer flat JPQL rewrites over derived roots for code that must run in compliance-strict environments","Track which queries use Hibernate-only syntax in a lint list so compliance flips are auditable"],"tags":["hql","jpa-compliance","derived-table","subquery","hibernate"],"backgroundTag":"strict-jpa-compliance-violation","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}