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

  1. Give the entity a real discriminator value instead of the 'not null' marker
  2. Where the marker semantics are required, express it as a predicate (discriminator is not null) instead of converting it to a literal
  3. 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

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


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