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
- 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
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
- 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
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
- NON_ENTITY_NAME
- UNMAPPED_POLYMORPHISM
- Implicitly-polymorphic domain path in subquery '${name}'
- Could not resolve entity or correlation path '${name}'
- FROM_FUNCTION
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/b53fe69f7175351a.
Report an issue: GitHub.