hibernate/hibernate-orm · error · MappingException
Discriminator formulas on joined inheritance hierarchies not
Error message
Discriminator formulas on joined inheritance hierarchies not supported at this time
What it means
When a polymorphic JOINED hierarchy declares an explicit discriminator mapping, JoinedSubclassEntityPersister inspects its first selectable and accepts only a real Column; anything else — a formula (@DiscriminatorFormula or XML <discriminator formula="...">) — fails boot with MappingException('Discriminator formulas on joined inheritance hierarchies not supported at this time'). Formulas work in SINGLE_TABLE hierarchies but not in JOINED ones.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/persister/entity/JoinedSubclassEntityPersister.java:186
final var dialect = creationContext.getDialect();
final var typeConfiguration = creationContext.getTypeConfiguration();
final var basicTypeRegistry = typeConfiguration.getBasicTypeRegistry();
// DISCRIMINATOR
if ( persistentClass.isPolymorphic() ) {
forceDiscriminator = persistentClass.isForceDiscriminator();
final var discriminatorMapping = persistentClass.getDiscriminator();
if ( discriminatorMapping != null ) {
LOG.tracef( "Encountered explicit discriminator mapping for joined inheritance" );
final var selectable = discriminatorMapping.getSelectables().get(0);
if ( selectable instanceof Column column ) {
explicitDiscriminatorColumnName = column.getQuotedName( dialect );
discriminatorAlias = column.getAlias( dialect, persistentClass.getRootTable() );
}
else {
throw new MappingException( "Discriminator formulas on joined inheritance hierarchies not supported at this time" );
}
discriminatorType = DiscriminatorHelper.getDiscriminatorType( persistentClass );
discriminatorValue = DiscriminatorHelper.getDiscriminatorValue( persistentClass );
discriminatorSQLString = DiscriminatorHelper.getDiscriminatorSQLValue( persistentClass, dialect );
}
else {
explicitDiscriminatorColumnName = null;
discriminatorAlias = IMPLICIT_DISCRIMINATOR_ALIAS;
discriminatorType = basicTypeRegistry.resolve( StandardBasicTypes.INTEGER );
try {
discriminatorValue = new DiscriminatorValue.Literal( persistentClass.getSubclassId() );
discriminatorSQLString = Integer.toString( persistentClass.getSubclassId() );
}
catch ( Exception e ) {
throw new MappingException( "Could not format discriminator value to SQL string", e );
}
}
}View on GitHub (pinned to fad1729dce)
Solutions
- Replace @DiscriminatorFormula with a real @DiscriminatorColumn on the joined hierarchy
- Remove the explicit discriminator mapping entirely — JOINED hierarchies work with Hibernate's implicit integer subclass ids
- If the formula is a hard requirement, keep SINGLE_TABLE inheritance where discriminator formulas are supported
Example fix
// before
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorFormula("case when type_code is null then 'P' else 'C' end")
public abstract class Billing { ... }
// after
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "billing_type", discriminatorType = STRING)
public abstract class Billing { ... } Defensive patterns
Strategy: validation
Validate before calling
Inheritance inh = root.getAnnotation(Inheritance.class);
if ( root.isAnnotationPresent(DiscriminatorFormula.class) && inh != null
&& inh.strategy() == InheritanceType.JOINED ) {
throw new IllegalStateException(
root.getName() + ": @DiscriminatorFormula is not supported with JOINED inheritance");
} Try / catch
try {
SessionFactory sf = metadata.getSessionFactoryBuilder().build();
}
catch ( org.hibernate.MappingException e ) {
throw new IllegalStateException("SessionFactory boot failed: " + e.getMessage(), e);
} Prevention
- When switching inheritance strategies, re-validate all discriminator annotations on the root
- Reserve @DiscriminatorFormula for SINGLE_TABLE hierarchies
- Add a boot test per inheritance hierarchy configuration
When it happens
Trigger: @Inheritance(strategy = JOINED) on the root combined with @DiscriminatorFormula (or an XML discriminator formula) while the hierarchy declares an explicit discriminator mapping; polymorphic joined hierarchies whose discriminator is a computed SQL expression (CASE, view column).
Common situations: Deriving the discriminator from a computed column or expression; migrating a SINGLE_TABLE hierarchy that used a formula to JOINED; DBA mandates that the type marker be an expression rather than a stored column.
Related errors
- Illegal discriminator type: {discriminatorType}
- Could not parse discriminator value '{discriminatorValue}' a
- Expecting just a single formula/column in context of <%s nam
- subclass key mapping has wrong number of columns: " + getEnt
- Circular inheritance mapping: '" + subclass.getEntityName()
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/f9bf7777f8edcaaa.
Report an issue: GitHub.