hibernate/hibernate-orm · error · DuplicateMappingException

Duplicate entity definition '%s'

Error message

Duplicate entity definition '%s'

What it means

Entities are registered in the InFlightMetadataCollector keyed by their Hibernate entity name (the fully-qualified class name unless overridden). addEntityBinding throws DuplicateMappingException(Type.ENTITY) with 'Duplicate entity definition' when an entity name is already present in entityBindingMap - the same entity name was mapped twice.

Source

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

		return entityBindingMap.values();
	}

	@Override
	public Map<String, PersistentClass> getEntityBindingMap() {
		return entityBindingMap;
	}

	@Override
	public PersistentClass getEntityBinding(String entityName) {
		return entityBindingMap.get( entityName );
	}

	@Override
	public void addEntityBinding(PersistentClass persistentClass) throws DuplicateMappingException {
		final String entityName = persistentClass.getEntityName();
		final String jpaEntityName = persistentClass.getJpaEntityName();
		if ( entityBindingMap.containsKey( entityName ) ) {
			throw new DuplicateMappingException( DuplicateMappingException.Type.ENTITY, entityName );
		}

		for ( var existingPersistentClass : entityBindingMap.values() ) {
			if ( existingPersistentClass.getJpaEntityName().equals( jpaEntityName ) ) {
				throw new DuplicateMappingException(
						String.format(
								"Entity classes [%s] and [%s] share the entity name '%s' (entity names must be distinct)",
								existingPersistentClass.getClassName(),
								persistentClass.getClassName(),
								jpaEntityName
						),
						DuplicateMappingException.Type.ENTITY,
						jpaEntityName
				);
			}
		}

		entityBindingMap.put( entityName, persistentClass );

View on GitHub (pinned to fad1729dce)

Solutions

  1. Locate the duplicate named in the message: check every <mapping> element in cfg.xml, <class> in persistence.xml, and every MetadataSources.addAnnotatedClassName/addResource call
  2. Remove the duplicate so each entity is mapped through exactly one source
  3. If two genuinely different mappings must coexist, give one an explicit distinct entity name (@Entity(name=...) / <class name=...>)
  4. When adding classes programmatically, deduplicate with a Set before adding

Example fix

<!-- before: same entity mapped twice -->
<mapping class="com.acme.User"/>
<mapping resource="com/acme/User.hbm.xml"/>

<!-- after: exactly one mapping per entity -->
<mapping class="com.acme.User"/>
Defensive patterns

Strategy: try-catch

Validate before calling

// Deduplicate programmatic mapping sources before adding
Set<String> unique = new LinkedHashSet<>(annotatedClassNames);
annotatedClassNames.clear();
annotatedClassNames.addAll(unique);

Try / catch

try {
    SessionFactory sf = metadata.buildSessionFactory();
}
catch (DuplicateMappingException e) {
    // e.getMessage() names the duplicated entity: find the second mapping
    // (cfg.xml <mapping>, persistence.xml <class>, hbm.xml, programmatic) and remove it
}

Prevention

When it happens

Trigger: The same entity name mapped through two channels: a class listed both as annotated class and via hbm.xml resource; duplicate <mapping class=...> or persistence.xml <class> entries; two mappings declaring the same explicit entity name; or programmatic addEntityBinding called twice for the same name.

Common situations: persistence.xml <class> plus hibernate.cfg.xml <mapping resource> for the same entity; module merges where two modules both map a shared entity; copy-pasted mapping entries; wildcard scanning pulling the same resource twice.

Related errors


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