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

  1. Drop the constraint column list — plain 'on conflict do nothing' is the shape the base translator supports.
  2. Use the dialect's native upsert through a native SQL query (e.g., INSERT ... ON CONFLICT / MERGE / ON DUPLICATE KEY UPDATE).
  3. 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

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


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