hibernate/hibernate-orm · error · UnsupportedOperationException

dynamic instantiation in a sub-query is unsupported

Error message

dynamic instantiation in a sub-query is unsupported

What it means

DynamicInstantiation models 'select new X(...) ...' (constructor or list/map injection) in the SELECT clause. It supports building a DomainResult for the top-level query, but when the dynamic instantiation ends up inside a sub-query, applySqlSelections() is called on it and it throws UnsupportedOperationException('dynamic instantiation in a sub-query is unsupported') - Hibernate cannot propagate instantiation targets through the subquery boundary into SQL select items.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/sql/results/graph/instantiation/internal/DynamicInstantiation.java:111

	}

	@Override
	public DomainResult<T> createDomainResult(
			String resultVariable,
			DomainResultCreationState creationState) {
		return new DynamicInstantiationResultImpl<>(
				resultVariable,
				getNature(),
				getTargetJavaType(),
				getArguments().stream()
						.map( argument -> argument.buildArgumentDomainResult( creationState ) )
						.collect( toList() )
		);
	}

	@Override
	public void applySqlSelections(DomainResultCreationState creationState) {
		throw new UnsupportedOperationException( "dynamic instantiation in a sub-query is unsupported" );
	}

//
//	@SuppressWarnings("unchecked")
//	private static DomainResultAssembler resolveAssembler(
//			DynamicInstantiation dynamicInstantiation,
//			boolean areAllArgumentsAliased,
//			boolean areAnyArgumentsAliased,
//			List<String> duplicatedAliases,
//			List<ArgumentReader<?>> argumentReaders,
//			AssemblerCreationState creationState) {
//
//		if ( dynamicInstantiation.getNature() == DynamicInstantiationNature.LIST ) {
//			if ( LOG.isDebugEnabled() && areAnyArgumentsAliased ) {
//				LOG.debug( "One or more arguments for List dynamic instantiation (`new list(...)`) specified an alias; ignoring" );
//			}
//			return new DynamicInstantiationListAssemblerImpl(
//					(JavaType<List>) dynamicInstantiation.getTargetJavaType(),

View on GitHub (pinned to fad1729dce)

Solutions

  1. Move the instantiation to the outer query: the subquery selects plain values (ids, scalars) and the outer select wraps them.
  2. Replace the subquery with a join so no instantiation is needed inside it.
  3. Fetch the raw subquery results first, then build the objects in Java (stream + map to DTO).
  4. Check the Hibernate JIRA and latest 6.x patch - restrictions around instantiation positions have shifted across releases.

Example fix

// before
em.createQuery("select o from Order o where o.id in " +
  "(select new com.acme.OrderRef(o2.id, o2.code) from Order o2 where o2.active = true)");

// after
em.createQuery("select new com.acme.OrderRef(o.id, o.code) from Order o " +
  "where o.id in (select o2.id from Order o2 where o2.active = true)");
Defensive patterns

Strategy: validation

Validate before calling

// Fail fast at startup: parsing the query builds the plan and throws immediately
try (EntityManager em = emf.createEntityManager()) {
    em.createQuery("select new com.acme.OrderRef(o.id, o.code) from Order o", OrderRef.class);
}
// And guard the JPQL string: no 'select new' inside a parenthesized subquery
String flat = jpql.toLowerCase().replaceAll("\\s+", " ");
if (flat.matches("(?s).*\\(\\s*select\\s+new\\b.*")) {
    throw new IllegalArgumentException("dynamic instantiation inside a sub-query is unsupported");
}

Try / catch

try {
    results = em.createQuery(jpql, Pair.class).getResultList();
} catch (UnsupportedOperationException e) {
    if ("dynamic instantiation in a sub-query is unsupported".equals(e.getMessage())) {
        // rewrite: instantiate in the outer query, select plain values in the subquery
    } else { throw e; }
}

Prevention

When it happens

Trigger: Using a constructor expression / dynamic instantiation inside a subquery, e.g. `where o.id in (select new com.acme.Pair(o2.id, o2.code) from Order o2)` or criteria subquery selections; dynamic instantiation nested in a query used as a derived table or in processing paths that require SQL selections from the subquery.

Common situations: Copy-pasting a working top-level projection into an exists/in subquery; criteria queries reusing a selection inside SubQuery expression lists; upgrading queries that worked in older 5.x builds where the restriction was less strict.

Related errors


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