{"record":{"id":"19bb016232226659","repo":"hibernate/hibernate-orm","slug":"couldn-t-find-conflict-constraint-column-constr","errorCode":null,"errorMessage":"Couldn't find conflict constraint column [${constraintColumnName}] in insert target columns: ${targetColumnNames}","messagePattern":"Couldn't find conflict constraint column \\[(.+?)\\] in insert target columns: (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/cte/CteInsertHandler.java","lineNumber":1317,"sourceCode":"\t\t\t\t\t\t\t\t\t\t\t\t\"excluded\",\n\t\t\t\t\t\t\t\t\t\t\t\tcolumnReference.getColumnExpression(),\n\t\t\t\t\t\t\t\t\t\t\t\tfalse,\n\t\t\t\t\t\t\t\t\t\t\t\tnull,\n\t\t\t\t\t\t\t\t\t\t\t\tcolumnReference.getJdbcMapping()\n\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\tbooleanType\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tcontinue OUTER;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ( errorIfMissing ) {\n\t\t\t\t// Should never happen\n\t\t\t\tfinal List<String> targetColumnNames = targetColumns.stream()\n\t\t\t\t\t\t.map( ColumnReference::getColumnExpression )\n\t\t\t\t\t\t.collect( Collectors.toList() );\n\t\t\t\tthrow new IllegalArgumentException( \"Couldn't find conflict constraint column [\" + constraintColumnName + \"] in insert target columns: \" + targetColumnNames );\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\t\treturn predicate;\n\t}\n\n\tprivate List<Assignment> getCompatibleAssignments(InsertSelectStatement dmlStatement, ConflictClause conflictClause) {\n\t\tif ( conflictClause.isDoNothing() ) {\n\t\t\treturn Collections.emptyList();\n\t\t}\n\t\tList<Assignment> compatibleAssignments = null;\n\t\tfinal List<Assignment> assignments = conflictClause.getAssignments();\n\t\tfor ( Assignment assignment : assignments ) {\n\t\t\tfor ( ColumnReference targetColumn : dmlStatement.getTargetColumns() ) {\n\t\t\t\tif ( assignment.getAssignable().getColumnReferences().contains( targetColumn ) ) {\n\t\t\t\t\tif ( compatibleAssignments == null ) {\n\t\t\t\t\t\tcompatibleAssignments = new ArrayList<>( assignments.size() );\n\t\t\t\t\t}","sourceCodeStart":1299,"sourceCodeEnd":1335,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/cte/CteInsertHandler.java#L1299-L1335","documentation":"When an explicit ON CONFLICT column cannot be found among the insert's target columns, buildColumnMatchPredicate throws this IllegalArgumentException (errorIfMissing=true path). The emulation needs each named conflict column to also be an inserted column so it can build the match predicate — unlike native SQL where the conflict index column need not be inserted.","triggerScenarios":"`insert into Customer(id, name) select ... on conflict (email)` — email is named as the conflict column but is absent from the target column list; renaming attributes so the conflict clause references a property no longer inserted.","commonSituations":"Writing HQL `on conflict (col)` with PostgreSQL-native semantics in mind (where the referenced index column doesn't have to appear in the INSERT list); partial insert column lists combined with unique-key conflict handling.","solutions":["Add the conflict column to the insert target list: `insert into Customer(id, email, name) ... on conflict (email)`","Choose a conflict column that IS among the inserted columns","Validate at query-build time that every conflict column is in the target list"],"exampleFix":"// before\ninsert into Customer(id, name)\nselect l.id, l.name from Lead l\non conflict (email)\n\n// after\ninsert into Customer(id, email, name)\nselect l.id, l.email, l.name from Lead l\non conflict (email)","handlingStrategy":"validation","validationCode":"// Validate: every explicit conflict column must be an insert target column\nSet<String> targets = new HashSet<>(targetColumns);\nfor (String c : conflictColumns) {\n    if (!targets.contains(c)) {\n        throw new IllegalArgumentException(\n            \"Conflict column \" + c + \" must also appear in the insert target list\");\n    }\n}","typeGuard":null,"tryCatchPattern":"try {\n    em.createQuery(insertHql).executeUpdate();\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"Couldn't find conflict constraint column\")) {\n        throw new QueryBuildException(\"Add the conflict column to the insert target list\", e);\n    }\n    throw e;\n}","preventionTips":["Treat ON CONFLICT columns as a subset of the insert column list in HQL (unlike native SQL)","When renaming attributes, update both the target list and the conflict clause","Centralize upsert HQL in reviewed constants rather than ad-hoc strings"],"tags":["hql","upsert","on-conflict","insert-select","hibernate-6"],"backgroundTag":"upsert-conflict-column-inference","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}