{"record":{"id":"665a83f67388c750","repo":"hibernate/hibernate-orm","slug":"insert-conflict-do-update-clause-with-constraint-665a83","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-core/src/main/java/org/hibernate/dialect/sql/ast/SybaseSqlAstTranslator.java","lineNumber":99,"sourceCode":"\t\t\tclauseStack.push( Clause.DELETE );\n\t\t\trenderDmlTargetTableExpression( statement.getTargetTable() );\n\t\t}\n\t\tfinally {\n\t\t\tclauseStack.pop();\n\t\t}\n\t\tvisitFromClause( statement.getFromClause() );\n\t}\n\n\t@Override\n\tprotected void renderFromClauseAfterUpdateSet(UpdateStatement statement) {\n\t\tvisitFromClause( statement.getFromClause() );\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// Sybase does not allow CASE expressions where all result arms contain plain parameters.\n\t// At least one result arm must provide some type context for inference,\n\t// so we cast the first result arm if we encounter this condition\n\n\t@Override\n\tprotected void visitAnsiCaseSearchedExpression(\n\t\t\tCaseSearchedExpression caseSearchedExpression,\n\t\t\tConsumer<Expression> resultRenderer) {\n\t\tif ( getParameterRenderingMode() == SqlAstNodeRenderingMode.DEFAULT\n\t\t\t\t&& areAllResultsParameters( caseSearchedExpression ) ) {\n\t\t\tfinal List<CaseSearchedExpression.WhenFragment> whenFragments = caseSearchedExpression.getWhenFragments();\n\t\t\tfinal Expression firstResult = whenFragments.get( 0 ).getResult();\n\t\t\tsuper.visitAnsiCaseSearchedExpression(\n\t\t\t\t\tcaseSearchedExpression,","sourceCodeStart":81,"sourceCodeEnd":117,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/dialect/sql/ast/SybaseSqlAstTranslator.java#L81-L117","documentation":"SybaseSqlAstTranslator (SQL Anywhere family) visitConflictClause rejects the constraint-name form of the HQL upsert conflict clause: a DO UPDATE clause with a non-null constraint name ('on conflict on constraint <name> do update') throws IllegalQueryOperationException during translation, since the dialect rendering cannot anchor an upsert conflict to a named constraint.","triggerScenarios":"HQL 'insert into ... on conflict on constraint <name> do update set ...' executed against SQLAnywhereDialect (or another dialect using SybaseSqlAstTranslator); throws from createQuery/executeUpdate during SQL generation.","commonSituations":"Sharing upsert HQL between PostgreSQL and SQL Anywhere deployments; copying the Hibernate 6.6+ 'on conflict' documentation examples; migration projects that keep PostgreSQL idioms.","solutions":["Switch to 'on conflict (col1, col2) do update set ...'","Make sure the column list equals the unique constraint's columns so behavior is identical","Use a native SQL Anywhere upsert/MERGE for dialect-specific behavior","Keep a dialect-specific HQL branch for the constraint-name variant"],"exampleFix":"// before\n\"insert into Tag t (t.name,t.hits) values (:n,:h) on conflict on constraint uk_tag_name do update set t.hits = excluded.hits\"\n\n// after\n\"insert into Tag t (t.name,t.hits) values (:n,:h) on conflict (name) do update set t.hits = excluded.hits\"","handlingStrategy":"validation","validationCode":"static boolean supportsConstraintNameConflictTarget(Dialect dialect) {\n    return dialect instanceof PostgreSQLDialect; // Sybase translator rejects it\n}\n\nString target = supportsConstraintNameConflictTarget(dialect)\n    ? \"on constraint \" + constraintName\n    : \"(\" + String.join(\",\", constraintColumns) + \")\";\nString hql = \"insert into ... on conflict \" + target + \" do update set ...\";","typeGuard":null,"tryCatchPattern":"try {\n    em.createQuery(hql).executeUpdate();\n} catch (IllegalQueryOperationException e) {\n    if (e.getMessage().contains(\"constraint name is not supported\")) {\n        em.createQuery(withColumnTarget(hql)).executeUpdate();\n        return;\n    }\n    throw e;\n}","preventionTips":["Default to column-based conflict targets in shared code","Keep the unique-constraint -> columns mapping in config for easy rewriting","Include SQL Anywhere in the dialect test matrix when it is a supported deployment"],"tags":["hibernate","sql-anywhere","sybase","hql","upsert","on-conflict","insert"],"backgroundTag":"upsert-on-conflict-unsupported","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}