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
HSQLLegacySqlAstTranslator.visitConflictClause() rejects HQL INSERT ... ON CONFLICT clauses that name a constraint as the conflict target. HSQLDB supports upsert conflict clauses keyed by columns, but it has no 'ON CONFLICT ON CONSTRAINT <name>' syntax, so when conflictClause.isDoUpdate() and getConstraintName() != null Hibernate throws IllegalQueryOperationException during query translation.
Source
Thrown at hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/HSQLLegacySqlAstTranslator.java:93
}
}
@Override
protected void renderDerivedTableReference(DerivedTableReference tableReference) {
if ( tableReference instanceof FunctionTableReference && tableReference.isLateral() ) {
// No need for a lateral keyword for functions
tableReference.accept( this );
}
else {
super.renderDerivedTableReference( 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" );
}
}
}
@Override
protected void renderExpressionAsClauseItem(Expression expression) {
expression.accept( this );
}
@Override
public void visitBooleanExpressionPredicate(BooleanExpressionPredicate booleanExpressionPredicate) {
final boolean isNegated = booleanExpressionPredicate.isNegated();
if ( isNegated ) {
appendSql( "not(" );
}
booleanExpressionPredicate.getExpression().accept( this );
if ( isNegated ) {
appendSql( CLOSE_PARENTHESIS );View on GitHub (pinned to fad1729dce)
Solutions
- Change the conflict target to a column list: 'on conflict (name) do update set ...' — supported on HSQLDB
- Drop the conflict clause on HSQLDB and handle the unique-violation (DataIntegrityViolationException/ConstraintViolationException) yourself with a follow-up UPDATE
- Move the upsert to a native query for the HSQLDB profile
Example fix
// before (fails on HSQLDB) insert into Person (id, name) values (:id, :name) on conflict on constraint uk_person_name do update set name = excluded.name // after insert into Person (id, name) values (:id, :name) on conflict (name) do update set name = excluded.name
Defensive patterns
Strategy: validation
Validate before calling
static boolean usesConstraintConflictTarget(String hql) {
return hql.toLowerCase().matches("(?s).*on\\s+conflict\\s+on\\s+constraint.*");
}
if ( session.getJdbcServices().getDialect() instanceof HSQLLegacyDialect
&& usesConstraintConflictTarget(hql) ) {
throw new IllegalArgumentException("HSQLDB supports only column-target conflict clauses");
} Type guard
static boolean isLegacyHsqldb(Dialect d) { return d instanceof HSQLLegacyDialect; } Try / catch
try {
session.createQuery(hql).executeUpdate();
} catch (IllegalQueryOperationException e) {
if ( String.valueOf(e.getMessage()).contains("constraint name") ) {
// rewrite conflict target to a column list and retry
}
throw e;
} Prevention
- Prefer column-list conflict targets ('on conflict (col)') over constraint names - they are portable across Hibernate dialects
- Keep upsert HQL in one place so dialect-specific variants are easy to maintain
- Exercise upsert queries in the same database profile used in production, not only in the fastest test DB
When it happens
Trigger: Running an HQL insert with a constraint-named conflict target on HSQLLegacyDialect, e.g. 'insert into Person (id, name) select ... on conflict on constraint uk_person_name do update set name = excluded.name'. Only the DO UPDATE form with a constraint name is rejected; DO NOTHING and column-target forms pass through.
Common situations: Sharing one upsert @NamedQuery or criteria InsertSelectStatement across HSQLDB (tests) and PostgreSQL/SQLite (production), then the constraint-name form leaks into the HSQLDB test run; migrating upsert statements from a dialect that supports named constraints to HSQLDB in-memory tests.
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/3e753454213c270a.
Report an issue: GitHub.