hibernate/hibernate-orm · error · UnsupportedOperationException
INSERT cannot be basis for subquery
Error message
INSERT cannot be basis for subquery
What it means
SqmInsertSelectStatement.subquery throws UnsupportedOperationException because the JPA AbstractQuery.subquery() contract (derive a correlated subquery from this query) is meaningless for a DML statement: an INSERT ... SELECT cannot contain its own correlated subquery rooted on the insert itself, and SQL has no INSERT-in-subquery form. The method exists on the interface hierarchy; Hibernate implements it as an explicit rejection for insert-select statements.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/query/sqm/tree/spi/insert/SqmInsertSelectStatement.java:142
}
public SqmQueryPart<?> getSelectQueryPart() {
return selectQueryPart;
}
public void setSelectQueryPart(SqmQueryPart<?> selectQueryPart) {
this.selectQueryPart = selectQueryPart;
}
@Override
public <X> X accept(SemanticQueryWalker<X> walker) {
return walker.visitInsertSelectStatement( this );
}
@Nonnull
@Override
public <U> Subquery<U> subquery(@Nonnull EntityType<U> type) {
throw new UnsupportedOperationException( "INSERT cannot be basis for subquery" );
}
@Nullable
@Override
public JpaPredicate getRestriction() {
// insert has no predicate
return null;
}
@Nonnull
@Override
public SqmInsertSelectStatement<T> setInsertionTargetPaths(@Nonnull Path<?>... insertionTargetPaths) {
super.setInsertionTargetPaths( insertionTargetPaths );
return this;
}
@Nonnull
@OverrideView on GitHub (pinned to fad1729dce)
Solutions
- Create the subquery on the source SELECT query instead: build the select as a CriteriaQuery and call subquery() on it, then attach the result to the insert
- Derive the subquery from the querySpec that feeds the insert-select
- Branch on statement type in generic code: skip subquery() for JpaCriteriaInsert/insert statements
- Model the logic as INSERT ... SELECT (subquery) — put the subquery inside the select list or where clause of the source query
Example fix
// before JpaCriteriaInsert<Person> ins = cb.createInsert( Person.class ); Subquery<Long> sq = ins.subquery( Long.class ); // UnsupportedOperationException // after CriteriaQuery<Person> source = cb.createQuery( Person.class ); Subquery<Long> sq = source.subquery( Long.class ); ins.setSelectQuery( source );
Defensive patterns
Strategy: type-guard
Validate before calling
if (statement instanceof org.hibernate.query.criteria.JpaCriteriaInsert) {
throw new IllegalArgumentException("subquery() not available on insert statements");
} Type guard
static boolean canHostSubquery(jakarta.persistence.criteria.AbstractQuery<?> q) {
return !(q instanceof org.hibernate.query.criteria.JpaCriteriaInsert<?>);
} Prevention
- Branch generic criteria handling on JpaCriteriaInsert before calling AbstractQuery methods
- Derive subqueries only from CriteriaQuery/SubQuery objects
- Keep DML and query pipelines separate in your data-access layer
When it happens
Trigger: Calling `insertStatement.subquery( SomeType.class )` on a JpaCriteriaInsert obtained from HibernateCriteriaBuilder's insert-select factory; generic criteria-processing code that handles all AbstractQuery subtypes uniformly and calls subquery() on each; reflectively invoking the full AbstractQuery API on any statement type.
Common situations: Utility frameworks (query enhancers, audit interceptors, count-wrappers) that accept AbstractQuery/CommonAbstractContract and try to derive subqueries; porting SELECT-query code paths to INSERT statements without branching on statement type; IDE autocomplete driving the call on an object typed as AbstractQuery.
Related errors
- INSERT query cannot be sub-query
- 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/4aaeabe5ff965a31.
Report an issue: GitHub.