hibernate/hibernate-orm · error · MappingException
UniqueKey {} already exists
Error message
UniqueKey {} already exists What it means
Table.addUniqueKey(UniqueKey) mirrors addIndex: it registers a unique constraint by name on a table and throws when a UniqueKey with that name already exists in uniqueKeys. Unique constraint names share the database namespace per table/schema, so Hibernate refuses silent overwriting and reports the colliding name.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/mapping/Table.java:478
}
public Index getIndex(String indexName) {
return indexes.get( indexName );
}
public Index addIndex(Index index) {
final var current = indexes.get( index.getName() );
if ( current != null ) {
throw new MappingException( "Index " + index.getName() + " already exists" );
}
indexes.put( index.getName(), index );
return index;
}
public UniqueKey addUniqueKey(UniqueKey uniqueKey) {
final var current = uniqueKeys.get( uniqueKey.getName() );
if ( current != null ) {
throw new MappingException( "UniqueKey " + uniqueKey.getName() + " already exists" );
}
uniqueKeys.put( uniqueKey.getName(), uniqueKey );
return uniqueKey;
}
/**
* Mark the given column unique and assign a name to the unique key.
* <p>
* This method does not add a {@link UniqueKey} to the table itself!
*/
public void createUniqueKey(Column column, MetadataBuildingContext context) {
final String keyName = context.getBuildingOptions().getImplicitNamingStrategy()
.determineUniqueKeyName( new ImplicitUniqueKeyNameSource() {
@Override
public Identifier getTableName() {
return name;
}
View on GitHub (pinned to fad1729dce)
Solutions
- Locate all @UniqueConstraint (and <unique-key>) declarations for the table and give each a distinct, descriptive name like uk_orders_order_number.
- Remove redundant duplicates that constrain the same column set.
- For programmatic mapping, check uniqueKeys.get(name) (or table.getUniqueKey(name)) before adding.
- Use a consistent naming scheme including the table name to avoid cross-subclass collisions.
Example fix
// before
@Table(name = "users", uniqueConstraints = {
@UniqueConstraint(name = "uk_email", columnNames = "email")
})
public class User { ... }
@AttributeOverrides... // subclass adds uk_email again to same table
// after — one constraint only, clearly named
@Table(name = "users", uniqueConstraints = {
@UniqueConstraint(name = "uk_users_email", columnNames = "email")
})
public class User { ... } Defensive patterns
Strategy: validation
Validate before calling
// programmatic mapping: check before add
if (table.getUniqueKey("uk_users_email") != null) {
// constraint already registered — skip or rename
} else {
table.addUniqueKey(uk);
} Try / catch
try {
metadata.buildMetadata().validate();
} catch (MappingException e) {
if (e.getMessage().matches("UniqueKey .+ already exists")) {
// duplicate @UniqueConstraint/<unique-key> name — dedupe
}
throw e;
} Prevention
- Prefix unique constraint names with the table name (uk_orders_order_number).
- Declare shared-table constraints once, on the hierarchy root.
- CI lint: gather all @UniqueConstraint names per table and fail on duplicates.
When it happens
Trigger: Two @UniqueConstraint(name = "uk_x", columnNames = {...}) entries resolving to the same table name; @Table(uniqueConstraints = ...) duplicated across SINGLE_TABLE subclasses that share one physical table; hbm.xml <unique-key name="x"/> declared twice for one table; programmatic table.addUniqueKey(...) called twice with the same name.
Common situations: Inheritance hierarchies where each subclass adds the same named constraint to the shared root table; refactors that moved @UniqueConstraint between class-level and property-level annotations leaving duplicates; merging XML mappings; DDL-generation tests after annotations were copy-pasted between related entities.
Related errors
- Index {} already exists
- SingleStore does not support dropping creating/dropping sche
- Unbreakable unique update cycle detected for SCC: %s
- Class '<componentClassName>' is an '@Embeddable' type and ma
- Property '<propertyName>' may not be annotated '@BatchSize'
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/f460b12115d3b81a.
Report an issue: GitHub.