{"record":{"id":"c4cadf18b16d55e8","repo":"hibernate/hibernate-orm","slug":"constraint-name-was-already-set-s","errorCode":null,"errorMessage":"Constraint name was already set: %s","messagePattern":"Constraint name was already set: (.+?)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/query/sqm/tree/spi/insert/SqmConflictClause.java","lineNumber":114,"sourceCode":"\tpublic JpaConflictClause<T> conflictOnConstraintAttributes(@Nonnull SingularAttribute<T, ?>... attributes) {\n\t\tfinal ArrayList<SqmPath<?>> paths = new ArrayList<>( attributes.length );\n\t\tfor ( SingularAttribute<T, ?> attribute : attributes ) {\n\t\t\tpaths.add( insertStatement.getTarget().get( attribute ) );\n\t\t}\n\t\treturn conflictOnConstraintPaths( paths );\n\t}\n\n\t@Nonnull\n\t@Override\n\tpublic SqmConflictClause<T> conflictOnConstraintPaths(@Nonnull Path<?>... paths) {\n\t\treturn conflictOnConstraintPaths( Arrays.asList( paths ) );\n\t}\n\n\t@Nonnull\n\t@Override\n\tpublic SqmConflictClause<T> conflictOnConstraintPaths(@Nonnull List<? extends Path<?>> paths) {\n\t\tif ( constraintName != null ) {\n\t\t\tthrow new IllegalStateException( \"Constraint name was already set: \" + constraintName );\n\t\t}\n\t\t//noinspection unchecked\n\t\tthis.constraintPaths = (List<SqmPath<?>>) Collections.unmodifiableList( paths );\n\t\treturn this;\n\t}\n\n\t@Nonnull\n\t@Override\n\tpublic List<SqmPath<?>> getConstraintPaths() {\n\t\treturn constraintPaths == null\n\t\t\t\t? Collections.emptyList()\n\t\t\t\t: constraintPaths;\n\t}\n\n\t@Nonnull\n\t@Override\n\tpublic SqmConflictUpdateAction<T> createConflictUpdateAction() {\n\t\treturn new SqmConflictUpdateAction<>( insertStatement );","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/spi/insert/SqmConflictClause.java#L96-L132","documentation":"SqmConflictClause.conflictOnConstraintPaths(List) throws IllegalStateException when a constraint name was already set — the mirror case of conflictOnConstraint. The ON CONFLICT clause's conflict target must be declared exactly once, either by unique-constraint name or by the set of index column paths; once constraintName is non-null, adding paths is refused because the two forms would produce contradictory SQL (`ON CONFLICT ON CONSTRAINT x (cols...)` is invalid).","triggerScenarios":"`insert.onConflict().conflictOnConstraint(\"uk_person_ssn\").conflictOnConstraintPaths(root.get(\"ssn\"))` — setting the name first, then paths; fluent chains that configure every available option; refactor leftovers where the columns call was added below an existing name call.","commonSituations":"Switching from named-constraint style to column-list style (common when moving to a database where constraint names differ between environments) without removing the old call; generated builders that emit both when both properties are configured; merging code from two upsert implementations.","solutions":["Remove the conflictOnConstraint(name) call and keep only the paths form (or vice versa)","Guard before adding paths: `if (clause.getConstraintName() == null) clause.conflictOnConstraintPaths(...)`","Make the conflict-target style a single configuration choice (one enum/flag) in your query-building layer, mapped to exactly one API call","Add a test that renders the final insert SQL once, catching double configuration early"],"exampleFix":"// before\ninsert.onConflict()\n     .conflictOnConstraint(\"uk_person_ssn\")\n     .conflictOnConstraintPaths( root.get(\"ssn\") ); // IllegalStateException\n\n// after\ninsert.onConflict()\n     .conflictOnConstraint( \"uk_person_ssn\" );","handlingStrategy":"validation","validationCode":"if (clause.getConstraintName() == null) {\n    clause.conflictOnConstraintPaths( paths );\n} else {\n    throw new IllegalStateException(\"Conflict target already declared by name: \" + clause.getConstraintName());\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Pick one arbiter style per project and wrap it in a single helper","Remove the other call when switching conflict-target style","Build the conflict clause fresh per statement instead of mutating a shared template"],"tags":["hibernate","criteria-api","upsert","on-conflict","builder-state"],"backgroundTag":"upsert-conflict-clause-misuse","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}