hibernate/hibernate-orm · error · StrictJpaComplianceViolation

FROM_SUBQUERY

FROM_SUBQUERY

Error message

The JPA specification does not support subqueries in the from clause. Please disable the JPA query compliance if you want to use this feature.

What it means

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.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/query/hql/internal/SemanticQueryBuilder.java:2205

	@Override
	public SqmCteStatement<?> findCteStatement(String name) {
		if ( currentPotentialRecursiveCte != null && name.equals( currentPotentialRecursiveCte.getName() ) ) {
			return (SqmCteStatement<?>) currentPotentialRecursiveCte;
		}
		return processingStateStack.findCurrentFirstWithParameter( name, SemanticQueryBuilder::matchCteStatement );
	}

	private static SqmCteStatement<?> matchCteStatement(SqmCreationProcessingState state, String n) {
		return state.getProcessingQuery() instanceof SqmCteContainer container
				? container.getCteStatement( n )
				: null;
	}

	@Override
	public SqmRoot<?> visitRootSubquery(HqlParser.RootSubqueryContext ctx) {
		if ( getCreationOptions().useStrictJpaCompliance() ) {
			throw new StrictJpaComplianceViolation(
					"The JPA specification does not support subqueries in the from clause. " +
							"Please disable the JPA query compliance if you want to use this feature.",
					StrictJpaComplianceViolation.Type.FROM_SUBQUERY
			);
		}

		final var subQuery = (SqmSubQuery<?>) ctx.subquery().accept( this );
		final String alias = extractAlias( ctx.variable() );
		final var sqmRoot = new SqmDerivedRoot<>( subQuery, alias );
		processingStateStack.getCurrent().getPathRegistry().register( sqmRoot );
		return sqmRoot;
	}

	@Override
	public SqmRoot<?> visitRootFunction(HqlParser.RootFunctionContext ctx) {
		if ( getCreationOptions().useStrictJpaCompliance() ) {
			throw new StrictJpaComplianceViolation(
					"The JPA specification does not support functions in the from clause. " +

View on GitHub (pinned to fad1729dce)

Solutions

  1. Disable the query compliance flag: 'hibernate.jpa.compliance.query=false'
  2. Rewrite the query as a flat query with the subquery moved to a where-clause subquery or a plain join
  3. Map the derived table as an entity backed by @Subselect, or use a native query for this read

Example fix

# before
hibernate.jpa.compliance.query=true
select s.dept from (select distinct e.dept from Employee e) s

# after
hibernate.jpa.compliance.query=false
Defensive patterns

Strategy: fallback

Validate before calling

static boolean strictQueryCompliance(EntityManagerFactory emf) {
    Object v = emf.getProperties().get("hibernate.jpa.compliance.query");
    if (v == null) v = emf.getProperties().get("hibernate.jpa.compliance");
    return v != null && Boolean.parseBoolean(v.toString());
}

static boolean usesFromSubquery(String hql) {
    return java.util.regex.Pattern.compile("\\bfrom\\s*\\(", java.util.regex.Pattern.CASE_INSENSITIVE).matcher(hql).find();
}

if (strictQueryCompliance(emf) && usesFromSubquery(hql)) { /* use the flat rewrite */ }

Type guard

static boolean isFromSubqueryViolation(Throwable t) {
    return t instanceof org.hibernate.query.sqm.StrictJpaComplianceViolation
            && ((org.hibernate.query.sqm.StrictJpaComplianceViolation) t).getType() == org.hibernate.query.sqm.StrictJpaComplianceViolation.Type.FROM_SUBQUERY;
}

Try / catch

try {
    return em.createQuery(derivedRootHql, Tuple.class).getResultList();   // from (select ...) s
} catch (org.hibernate.query.sqm.StrictJpaComplianceViolation e) {
    return em.createQuery(flatJpqlRewrite, Tuple.class).getResultList(); // equivalent flat JPQL
}

Prevention

When it happens

Trigger: '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.

Common situations: 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.

Related errors


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