hibernate/hibernate-orm · error · UnsupportedOperationException
INSERT query cannot be sub-query
Error message
INSERT query cannot be sub-query
What it means
SqmInsertValuesStatement.subquery throws UnsupportedOperationException for the same reason as insert-select: the JPA AbstractQuery.subquery() contract cannot apply to a DML statement. An INSERT ... VALUES is not a query expression — it cannot be nested or correlated — so any attempt to derive a subquery from it is rejected at the API level rather than producing invalid SQL later.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/query/sqm/tree/spi/insert/SqmInsertValuesStatement.java:146
verifyInsertTypesMatch( insertionTargetPaths, sqmValues.getExpressions() );
}
}
public List<SqmValues> getValuesList() {
return valuesList == null
? Collections.emptyList()
: Collections.unmodifiableList( valuesList );
}
@Override
public <X> X accept(SemanticQueryWalker<X> walker) {
return walker.visitInsertValuesStatement( this );
}
@Nonnull
@Override
public <U> Subquery<U> subquery(@Nonnull EntityType<U> type) {
throw new UnsupportedOperationException( "INSERT query cannot be sub-query" );
}
@Nullable
@Override
public JpaPredicate getRestriction() {
return null;
}
@Nonnull
@Override
public SqmInsertValuesStatement<T> setInsertionTargetPaths(@Nonnull Path<?>... insertionTargetPaths) {
super.setInsertionTargetPaths( insertionTargetPaths );
return this;
}
@Nonnull
@Override
public SqmInsertValuesStatement<T> setInsertionTargetPaths(@Nonnull List<? extends Path<?>> insertionTargetPaths) {View on GitHub (pinned to fad1729dce)
Solutions
- Attach subqueries to a separate CriteriaQuery/SubQuery used as a parameter value or comparison expression, not to the insert statement
- Move conditions needing subqueries into the WHERE of an insert-select variant: convert `insert ... values` into `insert ... select ... from dual-like source` if the dialect supports it
- In generic code, guard with `instanceof JpaCriteriaInsert` and skip subquery handling
- Compute the subquery result in Java beforehand and bind it as a parameter value
Example fix
// before JpaCriteriaInsertValues<Person> ins = cb.insertValues( Person.class ); Subquery<LocalDate> sq = ins.subquery( LocalDate.class ); // UnsupportedOperationException // after CriteriaQuery<LocalDate> q = cb.createQuery( LocalDate.class ); Subquery<LocalDate> sq = q.subquery( LocalDate.class ); ins.values( cb.parameter( Person.class ).get( "startDate" ) );
Defensive patterns
Strategy: type-guard
Validate before calling
if (statement instanceof org.hibernate.query.criteria.JpaCriteriaInsertValues) {
throw new IllegalArgumentException("subquery() not available on insert-values statements");
} Type guard
static boolean canHostSubquery(jakarta.persistence.criteria.AbstractQuery<?> q) {
return !(q instanceof org.hibernate.query.criteria.JpaCriteriaInsertValues<?>);
} Prevention
- Treat INSERT statements as terminals — never derive subqueries from them
- Precompute subquery results in Java and bind as parameters when nesting is impossible
- Type-check statement kinds in shared query interceptors
When it happens
Trigger: Calling `insertValuesStatement.subquery( type )` on a JpaCriteriaInsertValues from `cb.insertValues(...)`/equivalent; shared helpers that take AbstractQuery and unconditionally call subquery(); attempts to wrap a values-insert as an exists/count subquery at runtime.
Common situations: Generic query-manipulation layers (e.g., adding tenant filters or soft-delete checks via subqueries) applied uniformly to every query object; refactoring a criteria SELECT pipeline into INSERT statements; misunderstanding that in HQL/criteria only SELECT queries (and their parts) can host subqueries.
Related errors
- INSERT cannot be basis for subquery
- DELETE query cannot be sub-query
- Not correlated
- The JPA specification does not support subqueries in the fro
- Correlated derived root does not have an entity type. Use ge
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/eb402cf5883a8f97.
Report an issue: GitHub.