hibernate/hibernate-orm · error · IllegalStateException
Cannot convert NOT_NULL discriminator marker to a relational
Error message
Cannot convert NOT_NULL discriminator marker to a relational literal
What it means
DiscriminatorHelper.toRelationalValue converts a resolved DiscriminatorValue into a JDBC value: a Literal yields its value and the special NULL marker yields null, but the NOT_NULL marker (from the legacy @DiscriminatorValue("not null") mapping) has no single literal, so converting it throws IllegalStateException. Code paths that need a concrete bindable discriminator value (restrictions, insert parameter binding) fail for entities mapped with the marker.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/persister/entity/DiscriminatorHelper.java:102
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 ) {
return literal.value();
}
else if ( discriminatorValue == DiscriminatorValue.Special.NULL ) {
return null;
}
else {
throw new IllegalStateException( "Cannot convert NOT_NULL discriminator marker to a relational literal" );
}
}
private static <T> String discriminatorSqlLiteral(
BasicType<T> discriminatorType,
PersistentClass persistentClass,
Dialect dialect) {
return jdbcLiteral(
discriminatorType.getJavaTypeDescriptor().fromString( persistentClass.getDiscriminatorValue() ),
discriminatorType.getJdbcLiteralFormatter(),
dialect
);
}
public static <T> String jdbcLiteral(T value, JdbcLiteralFormatter<T> formatter, Dialect dialect) {
try {
return formatter.toJdbcLiteral( value, dialect, null );
}View on GitHub (pinned to fad1729dce)
Solutions
- Give the entity a real discriminator value instead of the 'not null' marker
- Where the marker semantics are required, express it as a predicate (discriminator is not null) instead of converting it to a literal
- Verify no framework or generated code binds discriminator literals for marker-mapped entities
Example fix
// before
@DiscriminatorValue("not null")
public class Miscellaneous extends Payment { }
// after
@DiscriminatorValue("MISC")
public class Miscellaneous extends Payment { } Defensive patterns
Strategy: validation
Validate before calling
DiscriminatorValue val = entity.getAnnotation(DiscriminatorValue.class);
if ( val != null && ("not null".equalsIgnoreCase(val.value())
|| "null".equalsIgnoreCase(val.value())) ) {
// marker value: never feed this entity's discriminator into literal conversion / insert binding
} Prevention
- Replace legacy 'null'/'not null' discriminator markers with real values during upgrades
- Treat the markers as predicates (IS NULL / IS NOT NULL) in custom SQL, not as literals
- Grep old hbm.xml files for discriminator-value="not null" before migrating
When it happens
Trigger: An entity mapped with @DiscriminatorValue("not null") — meaning 'rows with a non-null discriminator belong to this class' — followed by a call to toRelationalValue(...) or any runtime path that binds that entity's discriminator as a literal/parameter.
Common situations: Legacy Hibernate mappings carried forward from very old versions where 'null'/'not null' special discriminator markers were common; migrating such hierarchies onto code paths (inserts, criteria, filters) that need real literals.
Related errors
- Two different subclasses of '" + getEntityName() + "' map to
- Illegal discriminator type: {discriminatorType}
- Could not parse discriminator value '{discriminatorValue}' a
- Discriminator formulas on joined inheritance hierarchies not
- Expected object of type `%s`, but found `%s`; discriminator
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/c6e7bd62e3410428.
Report an issue: GitHub.