hibernate/hibernate-orm · error · DuplicateMappingException

Duplicate table mapping '{}'

Error message

Duplicate table mapping '{}'

What it means

DuplicateMappingException(Type.TABLE): the table-registration path (the snippet is the denormalized-table branch used by secondary tables and joined inheritance) found that a table with the same logical name already exists in the same catalog/schema namespace. Tables are keyed by (catalog, schema, name), so a collision means two mappings claim one table slot and bootstrap aborts.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/boot/internal/InFlightMetadataCollectorImpl.java:962

		// being set into the generated table (mainly to avoid later NPE), but for now we need to keep that :(
		final Identifier logicalName = name != null ? database.toIdentifier( name ) : null;
		if ( subselectFragment != null ) {
			return namespace.createDenormalizedTable(
					logicalName,
					physicalName -> new DenormalizedTable(
							buildingContext.getCurrentContributorName(),
							namespace,
							logicalName,
							subselectFragment,
							isAbstract,
							includedTable
					)
			);
		}
		else {
			if ( namespace.locateTable( logicalName ) != null ) {
				assert logicalName != null;
				throw new DuplicateMappingException( DuplicateMappingException.Type.TABLE, logicalName.toString() );
			}
			else {
				return namespace.createDenormalizedTable(
						logicalName,
						physicalTableName -> new DenormalizedTable(
								buildingContext.getCurrentContributorName(),
								namespace,
								physicalTableName,
								isAbstract,
								includedTable
						)
				);
			}
		}
	}


	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View on GitHub (pinned to fad1729dce)

Solutions

  1. Rename one of the colliding tables: compare the name in the message against every @Table, @SecondaryTable and @JoinTable declaration
  2. Verify a PhysicalNamingStrategy is not making two different logical names equal after normalization
  3. Ensure joined subclasses do not restate the parent table's name
  4. Re-run bootstrap after the rename; table duplicates always fail the build

Example fix

// before — secondary table collides with the primary table
@Entity
@Table(name = "orders")
@SecondaryTable(name = "orders", pkJoinColumns = @PrimaryKeyJoinColumn(name = "id"))

// after
@Entity
@Table(name = "orders")
@SecondaryTable(name = "order_details", pkJoinColumns = @PrimaryKeyJoinColumn(name = "order_id"))
Defensive patterns

Strategy: try-catch

Validate before calling

static void assertNoDuplicateTableNames( Class<?>... entityClasses ) {
    final Set<String> seen = new HashSet<>();
    for ( final Class<?> c : entityClasses ) {
        final Table t = c.getAnnotation( Table.class );
        if ( t != null && !seen.add( t.catalog() + '.' + t.schema() + '.' + t.name() ) ) {
            throw new IllegalStateException( "Duplicate table name: " + t.name() + " on " + c );
        }
        for ( final SecondaryTable st : c.getAnnotationsByType( SecondaryTable.class ) ) {
            if ( !seen.add( st.catalog() + '.' + st.schema() + '.' + st.name() ) ) {
                throw new IllegalStateException( "Duplicate table name: " + st.name() + " on " + c );
            }
        }
    }
}

Try / catch

try {
    sessionFactory = metadata.buildSessionFactory();
} catch ( DuplicateMappingException e ) {
    if ( e.getType() == DuplicateMappingException.Type.TABLE ) {
        throw new IllegalStateException( "Duplicate table mapping '" + e.getName() + "' — check @Table/@SecondaryTable/@JoinTable names and the naming strategy", e );
    }
    throw e;
}

Prevention

When it happens

Trigger: A @SecondaryTable whose name equals the entity's primary @Table or another secondary table; joined-subclass hierarchies with explicitly colliding table names; naming-strategy normalization making two distinct declarations converge to one name.

Common situations: Copy-pasted entities, refactors that renamed a primary table onto an existing secondary/join table name, and PhysicalNamingStrategies that add/strip prefixes so different declarations collapse to the same physical name.

Related errors


AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22). Data as JSON: /api/errors/fd610111c4a37229. Report an issue: GitHub.