hibernate/hibernate-orm · error · MappingException
Could not parse discriminator value '{discriminatorValue}' a
Error message
Could not parse discriminator value '{discriminatorValue}' as discriminator type '{discriminatorType}' What it means
DiscriminatorHelper.parseDiscriminatorValue takes the entity's discriminator literal (@DiscriminatorValue or XML discriminator-value) as a String and converts it with the discriminator BasicType's JavaTypeDescriptor.fromString(); any failure (e.g., NumberFormatException for 'GUEST' on an Integer discriminator) is wrapped in a MappingException that names both the value and the type. The check runs at SessionFactory boot, so a mismatched literal fails deployment immediately.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/persister/entity/DiscriminatorHelper.java:77
}
else if ( persistentClass.isDiscriminatorValueNotNull() ) {
return InFragment.NOT_NULL;
}
else {
return discriminatorSqlLiteral( getDiscriminatorType( persistentClass ), persistentClass, dialect );
}
}
private static DiscriminatorValue parseDiscriminatorValue(PersistentClass persistentClass) {
final BasicType<?> discriminatorType = getDiscriminatorType( persistentClass );
final String discriminatorValue = persistentClass.getDiscriminatorValue();
try {
return new DiscriminatorValue.Literal(
discriminatorType.getJavaTypeDescriptor().fromString( discriminatorValue )
);
}
catch ( Exception e ) {
throw new MappingException( "Could not parse discriminator value '" + discriminatorValue
+ "' as discriminator type '" + discriminatorType.getName() + "'", e );
}
}
public static DiscriminatorValue getDiscriminatorValue(PersistentClass persistentClass) {
if ( persistentClass.isDiscriminatorValueNull() ) {
return DiscriminatorValue.Special.NULL;
}
else if ( persistentClass.isDiscriminatorValueNotNull() ) {
return DiscriminatorValue.Special.NOT_NULL;
}
else {
return parseDiscriminatorValue( persistentClass );
}
}
public static Object toRelationalValue(DiscriminatorValue discriminatorValue) {
if ( discriminatorValue instanceof DiscriminatorValue.Literal literal ) {View on GitHub (pinned to fad1729dce)
Solutions
- Make the @DiscriminatorValue text parseable by the @DiscriminatorColumn type ('1' for INTEGER, a single character for CHAR)
- Or change @DiscriminatorColumn(discriminatorType = ...) to match the literal format you want to use
- Omit @DiscriminatorValue to fall back to defaults (entity name for STRING, subclass ids for implicit)
Example fix
// before
@Inheritance(SINGLE_TABLE)
@DiscriminatorColumn(name = "kind", discriminatorType = DiscriminatorType.INTEGER)
@DiscriminatorValue("GUEST")
// after
@Inheritance(SINGLE_TABLE)
@DiscriminatorColumn(name = "kind", discriminatorType = DiscriminatorType.INTEGER)
@DiscriminatorValue("1") Defensive patterns
Strategy: validation
Validate before calling
DiscriminatorColumn col = entity.getAnnotation(DiscriminatorColumn.class);
DiscriminatorValue val = entity.getAnnotation(DiscriminatorValue.class);
if ( val != null && col != null ) {
switch ( col.discriminatorType() ) {
case INTEGER -> Integer.parseInt(val.value()); // NumberFormatException => invalid mapping
case CHAR -> { if ( val.value().length() != 1 ) throw new IllegalArgumentException("CHAR literal must be 1 char"); }
default -> { } // STRING always parses
}
} Try / catch
try {
SessionFactory sf = metadata.getSessionFactoryBuilder().build();
}
catch ( org.hibernate.MappingException e ) {
throw new IllegalStateException("SessionFactory boot failed: " + e.getMessage(), e);
} Prevention
- Check every @DiscriminatorValue against the @DiscriminatorColumn type when either changes
- Generate a test that boots the full hierarchy; all subclasses' literals are validated at boot
- Prefer STRING discriminators unless the schema mandates numeric ones
When it happens
Trigger: @DiscriminatorValue("GUEST") while @DiscriminatorColumn(discriminatorType = INTEGER); @DiscriminatorValue("ABC") on a CHAR discriminator; enum-based discriminators whose literal does not match a constant name.
Common situations: DB column is numeric while entities carry textual discriminator values (or vice versa); overriding the discriminator type with @DiscriminatorColumn but keeping old literals; refactoring enum constants without updating @DiscriminatorValue strings.
Related errors
- Illegal discriminator type: {discriminatorType}
- Discriminator formulas on joined inheritance hierarchies not
- Root entity '<entityName>' is annotated '@DiscriminatorOptio
- Class '<className>' is not the root class of an entity inher
- Expecting just a single formula/column in context of <%s nam
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/499120addf00271b.
Report an issue: GitHub.