hibernate/hibernate-orm · error · MappingException
Could not format discriminator value to SQL string
Error message
Could not format discriminator value to SQL string
What it means
DiscriminatorHelper.jdbcLiteral renders a discriminator value as a SQL literal for the active dialect by delegating to the discriminator type's JdbcLiteralFormatter; any exception from the formatter is wrapped in MappingException('Could not format discriminator value to SQL string'). The literal parsed fine but could not be emitted — typically a custom or unusual discriminator Java/JDBC type whose formatter rejects the value or lacks dialect support. Reached via getDiscriminatorSQLValue() during persister construction.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/persister/entity/DiscriminatorHelper.java:122
}
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 );
}
catch (Exception e) {
throw new MappingException( "Could not format discriminator value to SQL string", e );
}
}
/**
* Utility that computes the node type used in entity or embeddable type literals. Resolves to
* either the {@link org.hibernate.metamodel.mapping.DiscriminatorType}, for polymorphic
* domain types, or to {@link StandardBasicTypes#CLASS Class} for non-inherited ones.
*/
public static <T> SqmBindableType<? super T> getDiscriminatorType(
SqmPathSource<T> domainType, NodeBuilder nodeBuilder) {
final SqmPathSource<?> subPathSource = domainType.findSubPathSource( DISCRIMINATOR_ROLE_NAME );
final SqmBindableType<?> type = subPathSource != null
? subPathSource.getPathType()
: nodeBuilder.getTypeConfiguration().getBasicTypeRegistry().resolve( StandardBasicTypes.CLASS );
//noinspection unchecked
return (SqmBindableType<? super T>) type;
}
}View on GitHub (pinned to fad1729dce)
Solutions
- Use a standard discriminator type (STRING/INTEGER/CHAR) via @DiscriminatorColumn
- Fix the custom type: implement/override JdbcLiteralFormatter so toJdbcLiteral() handles the discriminator value for every dialect you deploy on
- Add boot-time tests with each target dialect to catch formatter failures before deployment
Example fix
// before: custom type on the discriminator column lacking JdbcLiteralFormatter support @DiscriminatorColumn(name = "kind", discriminatorType = STRING) // + XML applies custom type // after: plain basic discriminator type with built-in formatter @DiscriminatorColumn(name = "kind", discriminatorType = STRING)
Defensive patterns
Strategy: try-catch
Try / catch
try {
SessionFactory sf = metadata.getSessionFactoryBuilder().build();
}
catch ( org.hibernate.MappingException e ) {
// discriminator literal could not be rendered for the dialect
throw new IllegalStateException("SessionFactory boot failed on dialect " + dialect + ": " + e.getMessage(), e);
} Prevention
- If you must use a custom discriminator type, implement and unit-test its JdbcLiteralFormatter for every production dialect
- Boot the factory in CI against every target database/dialect
- Prefer built-in discriminator types (STRING, INTEGER, CHAR)
When it happens
Trigger: A discriminator mapped with a custom BasicType/JavaType whose JdbcLiteralFormatter.toJdbcLiteral() throws for the mapped value; enum/char discriminators whose rendering path is unsupported on the target dialect; boot of the factory against a dialect the custom type never handled.
Common situations: Custom discriminator types introduced for legacy schemas; switching databases/dialects where literal rendering differs; values that parse via fromString() but cannot be rendered back.
Related errors
- Unable to determine SQL type name for column '%s' of table '
- Expecting just a single formula/column in context of <%s nam
- Class '" + typeName + "' does not implement '" + supertype.g
- Two different subclasses of '" + getEntityName() + "' map to
- Illegal discriminator type: {discriminatorType}
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/e8d3b24b6066176c.
Report an issue: GitHub.