hibernate/hibernate-orm · error · DuplicateMappingException
Table [%s] contains physical column name [%s] referred to by
Error message
Table [%s] contains physical column name [%s] referred to by multiple logical column names: [%s], [%s]
What it means
The mirror check of the logical-to-physical one: one physical column of a table was registered under a second, different logical name (Identifier equality is exact, so case or quoting differences count as different names). Because reverse resolution would be ambiguous, Hibernate throws DuplicateMappingException(Type.COLUMN_BINDING) and aborts bootstrap.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/boot/internal/InFlightMetadataCollectorImpl.java:1102
Locale.ENGLISH,
"Table [%s] contains logical column name [%s] referring to multiple physical " +
"column names: [%s], [%s]",
tableName,
logicalName,
existingPhysicalNameMapping,
physicalName
),
DuplicateMappingException.Type.COLUMN_BINDING,
tableName + "." + logicalName
);
}
}
}
private void bindPhysicalToLogical(Identifier logicalName, String physicalName) throws DuplicateMappingException {
final Identifier existingLogicalName = physicalToLogical.put( physicalName, logicalName );
if ( existingLogicalName != null && ! existingLogicalName.equals( logicalName ) ) {
throw new DuplicateMappingException(
String.format(
Locale.ENGLISH,
"Table [%s] contains physical column name [%s] referred to by multiple logical " +
"column names: [%s], [%s]",
tableName,
physicalName,
logicalName,
existingLogicalName
),
DuplicateMappingException.Type.COLUMN_BINDING,
tableName + "." + physicalName
);
}
}
}
private Map<Table,TableColumnNameBinding> columnNameBindingByTableMap;
View on GitHub (pinned to fad1729dce)
Solutions
- Give the column a single owning mapping and drop the redundant property, or mark the extra one insertable=false, updatable=false
- Where two mappings must coexist, align their logical names exactly (same spelling and quoting)
- Use @AssociationOverride/@AttributeOverride to bind embeddables to columns not otherwise mapped in that table
- Search the entity named in the message for duplicate name= values across @Column and @JoinColumn
Example fix
// before: FK column mapped twice under different logical names @ManyToOne @JoinColumn(name = "dept_id") private Department department; @Column(name = "dept_id") private Long deptId; // after: one owner; the read-only copy is non-insertable/non-updatable @ManyToOne @JoinColumn(name = "dept_id") private Department department; @Column(name = "dept_id", insertable = false, updatable = false) private Long deptId;
Defensive patterns
Strategy: try-catch
Validate before calling
static void assertNoRepeatedColumns( Class<?> entity ) {
final Map<String, String> columnOwner = new HashMap<>();
for ( Class<?> c = entity; c != null && c != Object.class; c = c.getSuperclass() ) {
for ( final Field f : c.getDeclaredFields() ) {
final Column col = f.getAnnotation( Column.class );
final JoinColumn join = f.getAnnotation( JoinColumn.class );
final String name = col != null ? col.name() : ( join != null ? join.name() : null );
if ( name != null && !name.isEmpty() ) {
final String prev = columnOwner.put( name.toLowerCase( Locale.ROOT ), f.getName() );
if ( prev != null ) {
throw new IllegalStateException( "Column '" + name + "' mapped by both '" + prev + "' and '" + f.getName() + "'" );
}
}
}
}
} Try / catch
try {
sessionFactory = metadata.buildSessionFactory();
} catch ( DuplicateMappingException e ) {
if ( e.getType() == DuplicateMappingException.Type.COLUMN_BINDING
&& e.getMessage() != null && e.getMessage().contains( "multiple logical" ) ) {
// one physical column referenced under two different logical names in the named table
throw new IllegalStateException( "Repeated column mapping: " + e.getMessage(), e );
}
throw e;
} Prevention
- Give each physical column exactly one owning mapping
- Mark read-only duplicates insertable=false, updatable=false
- Use @AssociationOverride/@AttributeOverride for embeddables sharing tables with their owner
- After renaming an attribute, delete its old column mapping instead of leaving both
When it happens
Trigger: Two properties of one entity mapped to the same physical column under different logical names — a @JoinColumn(name="dept_id") association plus a basic @Column(name="dept_id") field; an embeddable overridden onto a column the owner already maps; logical names differing only in case.
Common situations: The classic JPA 'repeated column' setup where a foreign key is exposed both as an association and as a plain field, legacy schemas mapped by multiple teams, and attribute renames that kept the old column mapping as a duplicate.
Related errors
- Table [%s] contains logical column name [%s] referring to mu
- Duplicate named query '%s'
- Duplicate named stored procedure '{}'
- Duplicate SQL result set mapping '{}'
- Duplicate table mapping '{}'
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/1d88faa25eb91020.
Report an issue: GitHub.