hibernate/hibernate-orm · error · IllegalQueryOperationException

Insert conflict 'do update' clause with constraint name is n

Error message

Insert conflict 'do update' clause with constraint name is not supported

What it means

HQL upserts ('insert ... on conflict do update') may name a conflict target constraint ('on conflict on constraint <name>'). HANALegacySqlAstTranslator.visitConflictClause throws IllegalQueryOperationException for that form: the legacy HANA translator's conflict rendering (HANA UPSERT emulation) cannot bind to a constraint by name.

Source

Thrown at hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/HANALegacySqlAstTranslator.java:145

			else {
				visitFromClause( statement.getFromClause() );
			}
		}
	}

	@Override
	protected void renderDmlTargetTableExpression(NamedTableReference tableReference) {
		super.renderDmlTargetTableExpression( tableReference );
		if ( getClauseStack().getCurrent() != Clause.INSERT ) {
			renderTableReferenceIdentificationVariable( tableReference );
		}
	}

	@Override
	protected void visitConflictClause(ConflictClause conflictClause) {
		if ( conflictClause != null ) {
			if ( conflictClause.isDoUpdate() && conflictClause.getConstraintName() != null ) {
				throw new IllegalQueryOperationException( "Insert conflict 'do update' clause with constraint name is not supported" );
			}
		}
	}

	protected boolean shouldEmulateFetchClause(QueryPart queryPart) {
		// HANA only supports the LIMIT + OFFSET syntax but also window functions
		// Check if current query part is already row numbering to avoid infinite recursion
		return useOffsetFetchClause( queryPart ) && getQueryPartForRowNumbering() != queryPart
				&& !isRowsOnlyFetchClauseType( queryPart );
	}

	@Override
	protected boolean isCorrelated(CteStatement cteStatement) {
		// Report false here, because apparently HANA does not need the "lateral" keyword to correlate a from clause subquery in a subquery
		return false;
	}

	@Override

View on GitHub (pinned to fad1729dce)

Solutions

  1. Remove the constraint name and let Hibernate infer the target: 'on conflict do update set ...'
  2. Use the column-list target 'on conflict (business_key) do update set ...' when you must pin the conflict target
  3. Rewrite as native HANA UPSERT via createNativeQuery for full control
  4. Plan migration off the legacy HANA dialect, whose translator handles modern conflict-clause features more completely

Example fix

// before (HQL, throws on HANA legacy dialect)
insert into Stock (sku, qty) select s.sku, s.qty from Stage s
  on conflict on constraint pk_stock do update set qty = excluded.qty

// after (column-list target)
insert into Stock (sku, qty) select s.sku, s.qty from Stage s
  on conflict (sku) do update set qty = excluded.qty
Defensive patterns

Strategy: validation

Validate before calling

Dialect d = sessionFactory.getJdbcServices().getDialect();
if (d instanceof org.hibernate.community.dialect.HANALegacyDialect && hql.contains("on conflict on constraint")) {
    hql = hql.replaceFirst("on constraint \\w+", ""); // or switch to column-list target
}

Type guard

static boolean namedConflictTargetSafe(Dialect d) {
    return !(d instanceof org.hibernate.community.dialect.HANALegacyDialect);
}

Try / catch

try {
    q = session.createQuery(hql);
} catch (org.hibernate.query.IllegalQueryOperationException e) {
    if (e.getMessage().contains("constraint name")) {
        q = session.createQuery(hql.replaceFirst("on constraint \\w+", ""));
    } else throw e;
}

Prevention

When it happens

Trigger: Executing an HQL insert whose conflict clause names a constraint, e.g. 'insert into Target ... select ... on conflict on constraint uk_target do update set ...', while the session uses the HANA legacy dialect. Target-less and column-list conflict targets are unaffected.

Common situations: HANA production databases pinned to the legacy dialect after a Hibernate upgrade; upsert HQL shared with PostgreSQL environments where the named-constraint form is natural; batch import jobs switching to the 6.6+ upsert syntax.

Related errors


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