{"record":{"id":"06c9c2d34832c606","repo":"hibernate/hibernate-orm","slug":"index-already-exists","errorCode":null,"errorMessage":"Index {} already exists","messagePattern":"Index (.+?) already exists","errorType":"exception","errorClass":"MappingException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/mapping/Table.java","lineNumber":469,"sourceCode":"\t\t\treturn index;\n\t\t}\n\t\telse {\n\t\t\tfinal var newIndex = new Index();\n\t\t\tnewIndex.setName( indexName );\n\t\t\tnewIndex.setTable( this );\n\t\t\tindexes.put( indexName, newIndex );\n\t\t\treturn newIndex;\n\t\t}\n\t}\n\n\tpublic Index getIndex(String indexName) {\n\t\treturn indexes.get( indexName );\n\t}\n\n\tpublic Index addIndex(Index index) {\n\t\tfinal var current =  indexes.get( index.getName() );\n\t\tif ( current != null ) {\n\t\t\tthrow new MappingException( \"Index \" + index.getName() + \" already exists\" );\n\t\t}\n\t\tindexes.put( index.getName(), index );\n\t\treturn index;\n\t}\n\n\tpublic UniqueKey addUniqueKey(UniqueKey uniqueKey) {\n\t\tfinal var current = uniqueKeys.get( uniqueKey.getName() );\n\t\tif ( current != null ) {\n\t\t\tthrow new MappingException( \"UniqueKey \" + uniqueKey.getName() + \" already exists\" );\n\t\t}\n\t\tuniqueKeys.put( uniqueKey.getName(), uniqueKey );\n\t\treturn uniqueKey;\n\t}\n\n\t/**\n\t * Mark the given column unique and assign a name to the unique key.\n\t * <p>\n\t * This method does not add a {@link UniqueKey} to the table itself!","sourceCodeStart":451,"sourceCodeEnd":487,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/mapping/Table.java#L451-L487","documentation":"Table.addIndex(Index) rejects registering a second index with the same name on one table. Index names must be unique per table (and in most databases per schema), so when the mapping layer or programmatic API tries to add an index whose name already exists in the table's index map, Hibernate throws this MappingException with the duplicated name.","triggerScenarios":"Two @Index(name = \"idx_x\", columnList = \"...\") annotations resolving to the same table with the same name; hbm.xml <index name=\"x\"/> appearing twice for one table; @Table(indexes = ...) plus an entity-level @Index with the same name; programmatic mapping calling table.addIndex(...) twice with equal names.","commonSituations":"Copy-pasted index annotations across entities mapped to one table (e.g. @Inheritance SINGLE_TABLE subclasses each adding indexes on the shared table); combining @Table(indexes=...) with a second redundant annotation after refactoring; XML and annotation sources merged for one table; schema-generation pipelines that union indexes from several mapping files.","solutions":["Search all entities and hbm files mapping the table named in the message for the index name, and make each @Index name unique (e.g. prefix with table name: idx_orders_custid).","If the duplication is intentional (same columns), keep exactly one declaration and delete the redundant one.","In programmatic models, guard with table.getIndex(name) != null before table.addIndex(index).","Adopt a naming convention (table_column_purpose) so hand-written index names cannot collide."],"exampleFix":"// before\n@Table(name = \"orders\", indexes = @Index(name = \"idx_cust\", columnList = \"customer_id\"))\npublic class Order { ... }\n@Index(name = \"idx_cust\", columnList = \"customer_email\") // duplicate name, same table\nprivate String email;\n\n// after\n@Index(name = \"idx_orders_email\", columnList = \"customer_email\")\nprivate String email;","handlingStrategy":"validation","validationCode":"// programmatic mapping: check before add\nif (table.getIndex(\"idx_orders_cust\") != null) {\n    // reuse existing index or pick another name\n} else {\n    table.addIndex(newIndex);\n}","typeGuard":null,"tryCatchPattern":"try {\n    metadata.buildMetadata().validate();\n} catch (MappingException e) {\n    if (e.getMessage().matches(\"Index .+ already exists\")) {\n        // duplicate @Index/<index> name on one table — dedupe names\n    }\n    throw e;\n}","preventionTips":["Name indexes <table>_<column(s)>_<purpose> to guarantee uniqueness.","For SINGLE_TABLE hierarchies, declare indexes once on the root entity.","Lint annotations in CI: collect @Index names per table and assert uniqueness."],"tags":["hibernate","index","schema","duplicate-name","orm-mapping"],"backgroundTag":"duplicate-constraint-name","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}