hibernate/hibernate-orm · error · IllegalQueryOperationException
Insert conflict clause with constraint column names is not s
Error message
Insert conflict clause with constraint column names is not supported
What it means
visitConflictClause is the base implementation for INSERT conflict clauses, and by design it only supports DO NOTHING with an optional constraint name (dialects with richer upsert support override it). If the SQM conflict clause names constraint column names — 'on conflict (col1, col2)' — and the active dialect's translator did not override conflict handling, translation fails with IllegalQueryOperationException.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstTranslator.java:1991
if ( hasAggregateFunctions( querySpec ) ) {
if ( followOnStrategy == Locking.FollowOn.DISALLOW ) {
throw new IllegalQueryOperationException( "Locking with aggregate functions is not supported" );
}
else if ( followOnStrategy == Locking.FollowOn.IGNORE ) {
return LockStrategy.NONE;
}
strategy = LockStrategy.FOLLOW_ON;
}
return strategy;
}
protected void visitConflictClause(ConflictClause conflictClause) {
if ( conflictClause != null ) {
// By default, we only support do nothing with an optional constraint name
if ( !conflictClause.getConstraintColumnNames().isEmpty() ) {
throw new IllegalQueryOperationException( "Insert conflict clause with constraint column names is not supported" );
}
if ( conflictClause.isDoUpdate() ) {
throw new IllegalQueryOperationException( "Insert conflict do update clause is not supported" );
}
}
}
protected void visitStandardConflictClause(ConflictClause conflictClause) {
if ( conflictClause == null ) {
return;
}
clauseStack.push( Clause.CONFLICT );
appendSql( " on conflict" );
final String constraintName = conflictClause.getConstraintName();
if ( constraintName != null ) {
appendSql( " on constraint " );
appendSql( constraintName );View on GitHub (pinned to fad1729dce)
Solutions
- Drop the constraint column list — plain 'on conflict do nothing' is the shape the base translator supports.
- Use the dialect's native upsert through a native SQL query (e.g., INSERT ... ON CONFLICT / MERGE / ON DUPLICATE KEY UPDATE).
- Handle the conflict in application logic: catch the constraint violation from a plain insert, or query-then-insert/update in a transaction.
Example fix
// before — conflict column names on a dialect without upsert support
session.createQuery(
"insert into Tag (id,name) values (:i,:n) on conflict (name) do nothing").executeUpdate();
// after — native upsert for that dialect, or plain insert + violation handling
em.createNativeQuery("insert into tag (id,name) values (?,?) on conflict (name) do nothing")
.setParameter(1, id).setParameter(2, name).executeUpdate(); Defensive patterns
Strategy: validation
Validate before calling
// base translator supports only DO NOTHING without constraint columns:
// gate the syntax before building HQL
if (!dialectSupportsUpsertColumns(sessionFactory)) { // per-dialect capability flag you maintain
hqlConflictClause = "on conflict do nothing"; // drop column names on basic dialects
} Try / catch
try { session.createQuery(insertHql).executeUpdate(); }
catch (org.hibernate.query.IllegalQueryOperationException e) {
if (e.getMessage().equals("Insert conflict clause with constraint column names is not supported")) {
session.createQuery(insertHqlWithoutConflictColumns()).executeUpdate();
} else { throw e; }
} Prevention
- Maintain a per-dialect capability map for upsert syntax and validate before issuing HQL.
- Prefer the simplest portable form 'on conflict do nothing' for multi-database code.
- Track Hibernate release notes — conflict-clause dialect support expands each minor.
When it happens
Trigger: HQL 'insert ... on conflict (col1, col2) do nothing' (constraint column names present) on a dialect whose translator still uses the base visitConflictClause — i.e., one without native or emulated upsert support.
Common situations: Using Hibernate 6.5+ HQL insert conflict clauses against older/less capable databases; enabling the feature in multi-dialect products (works on PostgreSQL, fails on a lesser-supported DB); community dialects not yet implementing conflict clause translation.
Related errors
- Can't emulate conflict clause with constraint name for more
- Insert conflict do update clause is not supported
- Insert conflict 'do update' clause with constraint name is n
- Insert conflict 'do update' clause with constraint name is n
- Insert conflict 'do update' clause with constraint name is n
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/204a594ff7476467.
Report an issue: GitHub.