hibernate/hibernate-orm · error · IllegalStateException

The JPA specification does not support subqueries having mul

Error message

The JPA specification does not support subqueries having multiple select items. Please disable the JPA query compliance if you want to use this feature.

What it means

With hibernate.jpa.compliance.query=true Hibernate enforces strict JPA semantics, and the JPA specification only allows a single select item in a subquery. Every multiselect(List) call on a subquery runs validateComplianceMultiselect(), which throws IllegalStateException when compliance is on, regardless of whether you actually passed multiple items — the JPA API itself does not permit the call on a subquery.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/query/sqm/tree/spi/select/SqmSubQuery.java:493

		}
		getQueryPart().setOrderByClause( sqmOrderByClause );
		return this;
	}

	@Override
	public JpaSubQuery<T> orderBy(List<Order> orders) {
		validateComplianceOrderBy();
		final SqmOrderByClause sqmOrderByClause = new SqmOrderByClause( orders.size() );
		for ( Order order : orders ) {
			sqmOrderByClause.addSortSpecification( (SqmSortSpecification) order );
		}
		getQueryPart().setOrderByClause( sqmOrderByClause );
		return this;
	}

	private void validateComplianceMultiselect() {
		if ( nodeBuilder().isJpaQueryComplianceEnabled() ) {
			throw new IllegalStateException(
					"The JPA specification does not support subqueries having multiple select items. " +
							"Please disable the JPA query compliance if you want to use this feature." );
		}
	}

	private void validateComplianceOrderBy() {
		if ( nodeBuilder().isJpaQueryComplianceEnabled() ) {
			throw new IllegalStateException(
					"The JPA specification does not support subqueries having an order by clause. " +
							"Please disable the JPA query compliance if you want to use this feature." );
		}
	}

	private void validateComplianceFetchOffset() {
		if ( nodeBuilder().isJpaQueryComplianceEnabled() ) {
			throw new IllegalStateException(
					"The JPA specification does not support subqueries having a fetch or offset clause. " +
							"Please disable the JPA query compliance if you want to use this feature." );

View on GitHub (pinned to fad1729dce)

Solutions

  1. Use a single select item on the subquery: subquery.select(oneExpression), selecting one column or an aggregate of the tuple
  2. Set hibernate.jpa.compliance.query=false if the Hibernate-specific multi-item subquery is intentional
  3. Move the multi-item projection out of the subquery: use a CTE (with(...)) or a derived table in the outer query

Example fix

// before (with hibernate.jpa.compliance.query=true)
sub.multiselect(root.get("id"), root.get("total")); // IllegalStateException

// after
sub.select(cb.tuple(root.get("id"), root.get("total"))); // still multi-item — instead:
sub.select(root.get("id")); // single item, JPA-compliant
Defensive patterns

Strategy: validation

Validate before calling

if (((SqmCriteriaNodeBuilder) cb).isJpaQueryComplianceEnabled()) {
    sub.select(singleExpression); // JPA allows only one item
} else {
    sub.multiselect(items);
}

Try / catch

try { sub.multiselect(items); } catch (IllegalStateException e) { if (e.getMessage().contains("multiple select items")) { sub.select(items.get(0)); } else throw e; }

Prevention

When it happens

Trigger: Setting hibernate.jpa.compliance.query=true (or spring.jpa.properties.hibernate.jpa.compliance.query=true, or enabling a global JpaCompliance setting) and then calling subquery.multiselect(list) or subquery.multiselect(item1, item2).

Common situations: Teams turning on full JPA compliance for certification or strictness after previously using Hibernate-specific multi-column subqueries; upgrading apps where compliance defaults were reviewed; shared codebases where one module enables compliance and another uses extended subquery features.

Related errors


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