{"record":{"id":"9a871991861f268b","repo":"hibernate/hibernate-orm","slug":"the-jpa-specification-does-not-support-subqueries","errorCode":null,"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":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/query/sqm/tree/spi/domain/AbstractSqmFrom.java","lineNumber":827,"sourceCode":"\t}\n\n\t@Nonnull\n\t@Override\n\tpublic <X> JpaFunctionJoin<X> joinArrayCollection(@Nonnull SingularAttribute<? super T, ? extends Collection<X>> collectionAttribute) {\n\t\treturn joinArrayCollection( collectionAttribute, SqmJoinType.INNER );\n\t}\n\n\t@Nonnull\n\t@Override\n\tpublic <X> JpaFunctionJoin<X> joinArrayCollection(\n\t\t\t@Nonnull SingularAttribute<? super T, ? extends Collection<X>> collectionAttribute,\n\t\t\t@Nonnull SqmJoinType joinType) {\n\t\treturn join( nodeBuilder().unnestCollection( get( collectionAttribute ) ), joinType, true );\n\t}\n\n\tprivate void validateComplianceFromSubQuery() {\n\t\tif ( nodeBuilder().isJpaQueryComplianceEnabled() ) {\n\t\t\tthrow new IllegalStateException(\n\t\t\t\t\t\"The JPA specification does not support subqueries in the from clause. \"\n\t\t\t\t\t+ \"Please disable the JPA query compliance if you want to use this feature.\" );\n\t\t}\n\t}\n\n\tprivate void validateComplianceFromFunction() {\n\t\tif ( nodeBuilder().isJpaQueryComplianceEnabled() ) {\n\t\t\tthrow new IllegalStateException(\n\t\t\t\t\t\"The JPA specification does not support functions in the from clause. \"\n\t\t\t\t\t+ \"Please disable the JPA query compliance if you want to use this feature.\" );\n\t\t}\n\t}\n\n\t@Nonnull\n\t@Override\n\tpublic <X> JpaCrossJoin<T, X> crossJoin(@Nonnull Class<X> entityJavaType) {\n\t\treturn crossJoin( nodeBuilder().getDomainModel().entity( entityJavaType ) );\n\t}","sourceCodeStart":809,"sourceCodeEnd":845,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/spi/domain/AbstractSqmFrom.java#L809-L845","documentation":"AbstractSqmFrom.validateComplianceFromSubQuery runs before Hibernate-specific FROM-clause joins of subqueries (derived tables / lateral joins, e.g. root.join(subQuery)); when JPA query compliance (hibernate.jpa.compliance.query) is enabled it throws IllegalStateException because the JPA specification only allows subqueries in WHERE/HAVING. The same validator guards the CTE/subquery join entry points on JpaFrom.","triggerScenarios":"root.join(subQuery) (join(JpaSubQuery, SqmJoinType, ...) path) while hibernate.jpa.compliance.query=true; using derived-table or lateral joins in the FROM clause of a criteria query in a compliant persistence unit.","commonSituations":"Turning on JPA compliance for portability/certification and having existing criteria queries that join subqueries in FROM; sharing query code between a compliant and a non-compliant persistence unit, so it only fails in one environment.","solutions":["Disable the setting: hibernate.jpa.compliance.query=false (xml property jakarta.persistence... or hibernate.jpa.compliance.query in persistence.xml/SessionFactory config).","Restructure the query to use a correlated subquery in the WHERE clause instead of a FROM join.","If the flag must stay on, move the Hibernate-specific query to HQL or a separate, non-compliant SessionFactory."],"exampleFix":"// before (hibernate.jpa.compliance.query=true)\nroot.join( idsSubQuery ); // subquery join in FROM -> IllegalStateException\n// after\n// persistence.xml: <property name=\"hibernate.jpa.compliance.query\" value=\"false\"/>\n// or restructure with a WHERE-clause subquery:\nquery.where( cb.exists( idsSubQuery ) );","handlingStrategy":"validation","validationCode":"if ( cb.isJpaQueryComplianceEnabled() ) {\n    // restructure: correlated subquery in WHERE instead of a FROM join\n    query.where( cb.exists( subquery ) );\n} else {\n    root.join( subQuery );\n}","typeGuard":"static boolean fromSubqueryJoinAllowed(HibernateCriteriaBuilder cb) {\n    return !cb.isJpaQueryComplianceEnabled();\n}","tryCatchPattern":null,"preventionTips":["Know whether hibernate.jpa.compliance.query is enabled in every persistence unit your query code touches.","Keep Hibernate-specific FROM-join queries in code paths only used with compliance disabled.","Prefer WHERE-clause subqueries for portable criteria code."],"tags":["hibernate","criteria-api","subquery","from-clause","jpa-compliance"],"backgroundTag":"jpa-compliance-violation","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}