hibernate/hibernate-orm · error · MappingException
Entities [%s] and [%s] are mapped with the same discriminato
Error message
Entities [%s] and [%s] are mapped with the same discriminator value '%s'.
What it means
In SINGLE_TABLE inheritance, Hibernate registers each entity of a hierarchy under its discriminator value in one map (subclassesByDiscriminatorValue). addSubclassByDiscriminatorValue detects that the same value was already registered and throws a MappingException naming both entities and the duplicated value. Boot fails because two rows with the same discriminator value could not be resolved to distinct classes.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/persister/entity/SingleTableEntityPersister.java:309
// Don't hold a reference to an empty HashMap:
subclassesByDiscriminatorValue = toSmallMap( subclassesByDiscriminatorValueLocal );
}
private static boolean isDiscriminatorInsertable(PersistentClass persistentClass) {
return !persistentClass.isDiscriminatorValueNull()
&& !persistentClass.isDiscriminatorValueNotNull()
&& persistentClass.isDiscriminatorInsertable()
&& !persistentClass.getDiscriminator().hasFormula();
}
private static void addSubclassByDiscriminatorValue(
Map<DiscriminatorValue, String> subclassesByDiscriminatorValue,
DiscriminatorValue discriminatorValue,
String entityName) {
final String mappedEntityName = subclassesByDiscriminatorValue.put( discriminatorValue, entityName );
if ( mappedEntityName != null ) {
throw new MappingException(
"Entities [" + entityName + "] and [" + mappedEntityName
+ "] are mapped with the same discriminator value '" + discriminatorValue + "'."
);
}
}
@Override
public boolean isInverseTable(int j) {
return isInverseTable[j];
}
@Override
public String getDiscriminatorColumnName() {
return discriminatorColumnName;
}
@Override
public String getDiscriminatorColumnReaders() {View on GitHub (pinned to fad1729dce)
Solutions
- Assign a unique @DiscriminatorValue to every class in the hierarchy (including the root)
- Check for values that are equal after case-folding or trimming and make them strictly distinct
- Review custom DiscriminatorType implementations for normalization that collapses distinct values
- Add a bootstrap test that asserts discriminator-value uniqueness per hierarchy (see validation)
Example fix
// before: two subclasses share the same value
@Entity @DiscriminatorValue("A") public class TypeA extends Base { }
@Entity @DiscriminatorValue("A") public class TypeB extends Base { }
// after: distinct values
@Entity @DiscriminatorValue("A") public class TypeA extends Base { }
@Entity @DiscriminatorValue("B") public class TypeB extends Base { } Defensive patterns
Strategy: validation
Validate before calling
// after Metadata build: assert discriminator-value uniqueness per hierarchy
Map<String, String> seenByRoot = new HashMap<>();
for (PersistentClass pc : metadata.getEntityBindings()) {
Object v = pc.getDiscriminatorValue();
if (v == null) continue;
String key = pc.getRootClass().getEntityName() + "::" + String.valueOf(v).trim().toLowerCase(Locale.ROOT);
if (seenByRoot.put(key, pc.getEntityName()) != null) {
throw new IllegalStateException("Duplicate discriminator value " + v + " in " + pc.getRootClass().getEntityName());
}
} Prevention
- Give every class in a hierarchy an explicit @DiscriminatorValue so collisions are visible in code review
- Avoid values that differ only by case or whitespace
- Run the uniqueness scan in CI so new subclasses cannot silently collide
When it happens
Trigger: Two @DiscriminatorValue("X") annotations on sibling subclasses (or one equal to the root's); values that collide after the discriminator type normalizes them ("A" vs "a" with a case-insensitive string type, 1 vs "1" with a custom DiscriminatorType); both subclasses (or the root and a subclass) leaving the value null.
Common situations: Copy-pasted subclasses that kept the same discriminator value; short codes like "S"/"s" meaning different things; refactors that merged or renamed branches of a hierarchy; custom discriminator types that map multiple inputs to the same key.
Related errors
- discriminator mapping required for single table polymorphic
- 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/454e61885d246435.
Report an issue: GitHub.