{"record":{"id":"1054d726a4b1a4f0","repo":"hibernate/hibernate-orm","slug":"duplicate-column","errorCode":null,"errorMessage":"Duplicate column: {}","messagePattern":"Duplicate column: (.+?)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/query/sqm/tree/spi/expression/SqmJsonTableFunction.java","lineNumber":293,"sourceCode":"\tpublic <X> JpaJsonValueNode<X> valueColumn(String columnName, JpaCastTarget<X> type) {\n\t\treturn columns.valueColumn( columnName, type );\n\t}\n\n\t@Override\n\tpublic JpaJsonTableColumnsNode nested(String jsonPath) {\n\t\treturn columns.nested( jsonPath );\n\t}\n\n\t@Override\n\tpublic JpaJsonTableFunction ordinalityColumn(String columnName) {\n\t\tcolumns.ordinalityColumn( columnName );\n\t\treturn this;\n\t}\n\n\tprivate void addColumn(String columnName) {\n\t\tcheckTypeResolved();\n\t\tif ( !columnNames.add( columnName ) ) {\n\t\t\tthrow new IllegalStateException( \"Duplicate column: \" + columnName );\n\t\t}\n\t}\n\n\tprivate void checkTypeResolved() {\n\t\tif ( isTypeResolved() ) {\n\t\t\tthrow new IllegalStateException(\n\t\t\t\t\t\"Type for json_table function is already resolved. Mutation is not allowed anymore\" );\n\t\t}\n\t}\n\n\t@Override\n\tpublic boolean equals(@Nullable Object object) {\n\t\treturn object instanceof SqmJsonTableFunction<?> that\n\t\t\t&& super.equals( object )\n\t\t\t&& columns.equals( that.columns )\n\t\t\t&& Objects.equals( passingExpressions, that.passingExpressions )\n\t\t\t&& errorBehavior == that.errorBehavior;\n\t}","sourceCodeStart":275,"sourceCodeEnd":311,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/spi/expression/SqmJsonTableFunction.java#L275-L311","documentation":"SqmJsonTableFunction tracks every column name in a set; column(), nested(), and ordinalityColumn() definitions funnel through addColumn(), which throws IllegalStateException('Duplicate column: name') when the name was already registered. Column names in the COLUMNS clause must be unique because they become tuple component names and SQL column aliases.","triggerScenarios":"Defining the same column name twice on a json_table criteria node: a path column named \"id\" plus ordinalityColumn(\"id\"), two path columns sharing one name, or nested columns whose chosen names collide with top-level ones.","commonSituations":"Loop-generated column lists containing duplicates; merging column definitions from several config sources; renames that accidentally produce a collision; names derived from JSON keys that repeat at different levels.","solutions":["De-duplicate the column list by name before building the function.","Rename one of the colliding columns - the SQL output name is independent of the JSON path, so alias it (e.g. id vs. id_ord).","When generating names dynamically, uniquify them (append an index) before calling column()/ordinalityColumn()."],"exampleFix":"// before\nt.ordinalityColumn( \"id\" );  // a path column \"id\" was already added -> Duplicate column: id\n\n// after\nt.ordinalityColumn( \"id_ord\" );","handlingStrategy":"validation","validationCode":"Set<String> usedColumnNames = new HashSet<>();\n\nvoid addJsonTableColumn(String name, Runnable definer) {\n    if ( !usedColumnNames.add( name ) ) {\n        throw new IllegalArgumentException( \"json_table column already defined: \" + name );\n    }\n    definer.run();\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Collect column names in a Set as you define them and fail fast on duplicates.","Uniquify generated names (append an index) before defining columns.","Review merged/loop-built column lists for repeated output names."],"tags":["hibernate","json-table","duplicate-column","criteria-api"],"backgroundTag":"duplicate-column-definition","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}