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

  1. Replace @DiscriminatorFormula with a real @DiscriminatorColumn on the joined hierarchy
  2. Remove the explicit discriminator mapping entirely — JOINED hierarchies work with Hibernate's implicit integer subclass ids
  3. 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 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


AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22). Data as JSON: /api/errors/f9bf7777f8edcaaa. Report an issue: GitHub.