hibernate/hibernate-orm · error · MappingException

Illegal discriminator type: {discriminatorType}

Error message

Illegal discriminator type: {discriminatorType}

What it means

DiscriminatorHelper.getDiscriminatorType(PersistentClass) extracts the entity discriminator's JDBC mapping and requires its Type to be a BasicType. A discriminator is a single-column value, so if the mapped Type is anything else (a component/composite type or a custom Type that does not resolve to BasicType) boot fails with MappingException('Illegal discriminator type'). Thrown while persisters are built at SessionFactory startup.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/persister/entity/DiscriminatorHelper.java:42

/**
 * Operations needed by persisters for working with discriminators.
 *
 * @author Gavin King
 */
@Internal
public class DiscriminatorHelper {

	/**
	 * The underlying BasicType as the "JDBC mapping" between the relational {@link org.hibernate.type.descriptor.java.JavaType}
	 * and the {@link org.hibernate.type.descriptor.jdbc.JdbcType}.
	 */
	static BasicType<?> getDiscriminatorType(PersistentClass persistentClass) {
		final Type discriminatorType = persistentClass.getDiscriminator().getType();
		if ( discriminatorType instanceof BasicType<?> basicType ) {
			return basicType;
		}
		else {
			throw new MappingException( "Illegal discriminator type: " + discriminatorType.getName() );
		}
	}

	public static BasicType<?> getDiscriminatorType(Component component) {
		final Type discriminatorType = component.getDiscriminator().getType();
		if ( discriminatorType instanceof BasicType<?> basicType ) {
			return basicType;
		}
		else {
			throw new MappingException( "Illegal discriminator type: " + discriminatorType.getName() );
		}
	}

	public static String getDiscriminatorSQLValue(PersistentClass persistentClass, Dialect dialect) {
		if ( persistentClass.isDiscriminatorValueNull() ) {
			return InFragment.NULL;
		}
		else if ( persistentClass.isDiscriminatorValueNotNull() ) {

View on GitHub (pinned to fad1729dce)

Solutions

  1. Map the discriminator with a standard basic type (String, Integer, char) via @DiscriminatorColumn
  2. Remove any custom @Type/UserType applied to the discriminator column
  3. If building boot metadata programmatically, ensure getDiscriminator().getType() resolves to a registered BasicType

Example fix

// before
@Entity
@DiscriminatorColumn(name = "kind", discriminatorType = STRING) // but a custom @Type is applied via XML/programmatic mapping

// after
@Entity
@DiscriminatorColumn(name = "kind", discriminatorType = STRING) // basic type only, no custom type override
Defensive patterns

Strategy: try-catch

Try / catch

try {
    SessionFactory sf = metadata.getSessionFactoryBuilder().build();
}
catch ( org.hibernate.MappingException e ) {
    // discriminator type is not a BasicType: fail deployment with e.getMessage()
    throw new IllegalStateException("SessionFactory boot failed: " + e.getMessage(), e);
}

Prevention

When it happens

Trigger: Mapping the entity discriminator with a non-basic type: a custom UserType/@Type on the discriminator column that is not a BasicType, a discriminator selectable backed by a composite type, or hand-built PersistentClass metadata whose getDiscriminator().getType() is not basic.

Common situations: Custom type registered for the discriminator column; exotic mappings where the discriminator is derived from a composite expression; custom metadata sources constructing PersistentClass programmatically.

Related errors


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