{"record":{"id":"f3fbc0189ab2b63e","repo":"hibernate/hibernate-orm","slug":"insert-conflict-do-update-clause-with-constraint-f3fbc0","errorCode":null,"errorMessage":"Insert conflict 'do update' clause with constraint name is not supported","messagePattern":"Insert conflict 'do update' clause with constraint name is not supported","errorType":"exception","errorClass":"IllegalQueryOperationException","httpStatus":null,"severity":"error","filePath":"hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/InformixSqlAstTranslator.java","lineNumber":214,"sourceCode":"\t@Override\n\tprotected void renderInsertIntoNoColumns(TableInsertStandard tableInsert) {\n\t\trenderIntoIntoAndTable( tableInsert );\n\t\tappendSql( \"values (0)\" );\n\t}\n\n\tprivate boolean supportsParameterOffsetFetchExpression() {\n\t\treturn getDialect().getVersion().isSameOrAfter( 11 );\n\t}\n\n\tprivate boolean supportsSkipFirstClause() {\n\t\treturn getDialect().getVersion().isSameOrAfter( 11 );\n\t}\n\n\t@Override\n\tprotected void visitConflictClause(ConflictClause conflictClause) {\n\t\tif ( conflictClause != null ) {\n\t\t\tif ( conflictClause.isDoUpdate() && conflictClause.getConstraintName() != null ) {\n\t\t\t\tthrow new IllegalQueryOperationException( \"Insert conflict 'do update' clause with constraint name is not supported\" );\n\t\t\t}\n\t\t}\n\t}\n\n\t@Override\n\tprotected void visitInsertStatementOnly(InsertSelectStatement statement) {\n\t\tif ( statement.getConflictClause() == null || statement.getConflictClause().isDoNothing() ) {\n\t\t\t// Render plain insert statement and possibly run into unique constraint violation\n\t\t\tsuper.visitInsertStatementOnly( statement );\n\t\t}\n\t\telse {\n\t\t\tvisitInsertStatementEmulateMerge( statement );\n\t\t}\n\t}\n\n\t@Override\n\tpublic void visitValuesTableReference(ValuesTableReference tableReference) {\n\t\temulateValuesTableReferenceColumnAliasing( tableReference );","sourceCodeStart":196,"sourceCodeEnd":232,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/InformixSqlAstTranslator.java#L196-L232","documentation":"InformixSqlAstTranslator.visitConflictClause() rejects HQL INSERT ... ON CONFLICT clauses whose conflict target is a named constraint with a DO UPDATE action. Informix upserts are emulated via MERGE (visitInsertStatementEmulateMerge), and a constraint-name target cannot be translated into that MERGE, so Hibernate throws IllegalQueryOperationException.","triggerScenarios":"Running 'insert into T (...) values/select ... on conflict on constraint <name> do update set ...' on InformixDialect. The check fires only when conflictClause.isDoUpdate() and getConstraintName() != null; column-list targets and do-nothing clauses are handled.","commonSituations":"Copy-pasting PostgreSQL/SQLite upsert statements into an Informix deployment; test fixtures using named constraints; shared repository code where the conflict target was written as a constraint to survive column renames.","solutions":["Use a column list as the conflict target: 'on conflict (cols) do update set ...'","On Informix, write the upsert as a native MERGE statement","Drop the conflict clause and handle the unique-violation exception with a compensating UPDATE"],"exampleFix":"// before (fails on Informix)\ninsert into Customer (id, email) values (:id, :email)\n  on conflict on constraint uk_customer_email do update set email = excluded.email\n\n// after\ninsert into Customer (id, email) values (:id, :email)\n  on conflict (email) do update set email = excluded.email","handlingStrategy":"validation","validationCode":"static boolean usesConstraintConflictTarget(String hql) {\n    return hql.toLowerCase().matches(\"(?s).*on\\\\s+conflict\\\\s+on\\\\s+constraint.*\");\n}\nif ( session.getJdbcServices().getDialect() instanceof InformixDialect\n        && usesConstraintConflictTarget(hql) ) {\n    throw new IllegalArgumentException(\"Informix upsert supports only column conflict targets\");\n}","typeGuard":"static boolean isInformix(Dialect d) { return d instanceof InformixDialect; }","tryCatchPattern":"try {\n    session.createQuery(hql).executeUpdate();\n} catch (IllegalQueryOperationException e) {\n    if ( String.valueOf(e.getMessage()).contains(\"constraint name\") ) {\n        // switch to 'on conflict (cols)' or a native MERGE statement\n    }\n    throw e;\n}","preventionTips":["Use column-target conflict clauses in shared HQL; constraint names are the least portable form","On Informix, validate upserts as native MERGE early in development","Keep a matrix of upsert syntax per target database next to your repository code"],"tags":["hibernate","informix","upsert","on-conflict","merge","insert"],"backgroundTag":"insert-on-conflict-unsupported","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}