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;
}
@OverrideView on GitHub (pinned to fad1729dce)
Solutions
- Remove the constraint name and let Hibernate infer the target: 'on conflict do update set ...'
- Use the column-list target 'on conflict (business_key) do update set ...' when you must pin the conflict target
- Rewrite as native HANA UPSERT via createNativeQuery for full control
- 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
- Prefer the target-less or column-list conflict clause in HQL shared across databases
- Track which dialects your upsert HQL must support, and run it against each in CI
- For full control of HANA upserts, use native UPSERT statements
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
- 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
- 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/f6aadb5d2d35be9e.
Report an issue: GitHub.