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 INSERT ... ON CONFLICT ... DO UPDATE where the conflict target is either column names or a named constraint (`on conflict on constraint <name>`). The Sybase legacy translator emulates do-update as a merge-style statement keyed on conflict column names; a constraint-name target provides no column list to match on, so visitConflictClause throws IllegalQueryOperationException for exactly the do-update + constraint-name combination.
Source
Thrown at hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SybaseLegacySqlAstTranslator.java:89
clauseStack.push( Clause.DELETE );
renderDmlTargetTableExpression( statement.getTargetTable() );
}
finally {
clauseStack.pop();
}
visitFromClause( statement.getFromClause() );
}
@Override
protected void renderFromClauseAfterUpdateSet(UpdateStatement statement) {
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" );
}
}
}
// Sybase does not allow CASE expressions where all result arms contain plain parameters.
// At least one result arm must provide some type context for inference,
// so we cast the first result arm if we encounter this condition
@Override
protected void visitAnsiCaseSearchedExpression(
CaseSearchedExpression caseSearchedExpression,
Consumer<Expression> resultRenderer) {
if ( getParameterRenderingMode() == SqlAstNodeRenderingMode.DEFAULT && areAllResultsParameters( caseSearchedExpression ) ) {
final List<CaseSearchedExpression.WhenFragment> whenFragments = caseSearchedExpression.getWhenFragments();
final Expression firstResult = whenFragments.get( 0 ).getResult();
super.visitAnsiCaseSearchedExpression(
caseSearchedExpression,
e -> {View on GitHub (pinned to fad1729dce)
Solutions
- Replace the constraint-name target with the conflict column list: `on conflict (email) do update set ...`
- Use `on conflict do nothing` when update-on-conflict is not required
- Execute the upsert as a native SQL statement
- Deduplicate in application code and issue a plain insert
Example fix
// before insert into Customer(id, email) select :id, :email on conflict on constraint uk_customer_email do update set email = :email // after insert into Customer(id, email) select :id, :email on conflict (email) do update set id = :id
Defensive patterns
Strategy: validation
Validate before calling
// Emit only column-targeted conflict clauses on Sybase
static String conflictClause(Dialect d) {
if (d instanceof SybaseLegacyDialect) {
return "on conflict (email) do update set id = :id"; // columns only
}
return "on conflict on constraint uk_customer_email do update set id = :id";
} Try / catch
try {
return em.createQuery(upsertHql).executeUpdate();
} catch (IllegalQueryOperationException e) {
if (e.getMessage() != null && e.getMessage().contains("constraint name")) {
// rebuild HQL with a column-list conflict target and retry
}
throw e;
} Prevention
- Prefer column-list conflict targets (`on conflict (cols)`); they are portable across all dialects
- Keep upsert HQL in one place so switching conflict-target syntax is a one-line change
- Test insert...on conflict statements against every backend in the support matrix
When it happens
Trigger: HQL `insert into Customer(id, email) select ... on conflict on constraint uk_customer_email do update set ...` executed with SybaseLegacyDialect (Sybase ASE). Column-list targets (`on conflict (email) do update`) and `do nothing` variants do not trigger this throw.
Common situations: Generic upsert code shared across databases that assumes the constraint-name syntax works everywhere; HQL upserts written against PostgreSQL semantics then run on Sybase ASE.
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/fd762f9fb3bff371.
Report an issue: GitHub.