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
Hibernate 6.6+ supports HQL upserts: 'insert into ... select ... on conflict ... do update'. SQL Server cannot bind the DO UPDATE action to a named constraint the way PostgreSQL does; SQLServerLegacySqlAstTranslator.visitConflictClause() detects 'on conflict on constraint X do update' during SQL translation and aborts with IllegalQueryOperationException.
Source
Thrown at hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SQLServerLegacySqlAstTranslator.java:137
}
}
@Override
protected void renderFromClauseAfterUpdateSet(UpdateStatement statement) {
if ( statement.getFromClause().getRoots().isEmpty() ) {
appendSql( " from " );
renderDmlTargetTableExpression( statement.getTargetTable() );
}
else {
visitFromClause( statement.getFromClause() );
}
}
@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" );
}
}
}
@Override
protected boolean needsRecursiveKeywordInWithClause() {
return false;
}
@Override
protected void renderTableGroupJoin(TableGroupJoin tableGroupJoin, List<TableGroupJoin> tableGroupJoinCollector) {
appendSql( WHITESPACE );
if ( tableGroupJoin.getJoinedGroup().isLateral() ) {
if ( tableGroupJoin.getJoinType() == SqlAstJoinType.LEFT ) {
appendSql( "outer apply " );
}
else {
appendSql( "cross apply " );View on GitHub (pinned to fad1729dce)
Solutions
- Use a column list as the conflict target: 'on conflict (id) do update set ...'
- Use 'on conflict do nothing', which needs no target
- Perform the upsert with a native MERGE statement on SQL Server
- Scan dynamic HQL for 'on conflict on constraint' before executing it against this dialect
Example fix
-- before (HQL) insert into Customer (id, email) select i.id, i.email from ImportRow i on conflict on constraint customer_pkey do update set email = excluded.email -- after (HQL) insert into Customer (id, email) select i.id, i.email from ImportRow i on conflict (id) do update set email = excluded.email
Defensive patterns
Strategy: validation
Validate before calling
boolean usesConstraintTarget(String hql, Dialect dialect) {
return hql != null
&& hql.toLowerCase( Locale.ROOT ).contains( "on conflict on constraint" )
&& dialect instanceof SQLServerLegacyDialect;
}
if ( usesConstraintTarget( hql, dialect ) ) {
hql = hql.replaceAll( "(?i)on constraint \\S+", "(id)" ); // column-list target
} Try / catch
try {
return session.createMutationQuery( hql ).executeUpdate();
}
catch ( IllegalQueryOperationException e ) {
// rewrite to 'on conflict (cols) do update' or run a native MERGE on SQL Server
throw e;
} Prevention
- Always use column-list conflict targets in portable HQL upserts
- Use native MERGE for SQL Server-specific upserts
- Run upsert queries against every target dialect in CI
When it happens
Trigger: Executing HQL like 'insert into Customer (id, email) select ... on conflict on constraint customer_pkey do update set email = excluded.email' on SQLServerLegacyDialect, or a Criteria insert-with-conflict built with a constraint-name conflict action.
Common situations: Porting PostgreSQL-native upsert HQL to SQL Server; shared repository code used against multiple databases where constraint-name targets were chosen for convenience.
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/f154ba0cc4ad2fe5.
Report an issue: GitHub.