hibernate/hibernate-orm · error · UnsupportedMappingException

Cannot apply TREAT operator to discriminator path

Error message

Cannot apply TREAT operator to discriminator path

What it means

TREAT (...) narrows an entity path to a subtype; applying it to a discriminator path (the result of TYPE(p)) is meaningless because the discriminator already is the subtype marker, not an entity reference. DiscriminatorSqmPath.treatAs(Class) therefore throws UnsupportedMappingException (a HibernateException, non-transient) to fail fast on such queries.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/query/sqm/spi/DiscriminatorSqmPath.java:112

	@Nonnull
	@Override
	default <N extends Number & Comparable<N>> NumericExpression<N> get(@Nonnull NumericAttribute<? super T, N> attribute) {
		throw new IllegalStateException( "Discriminator cannot be de-referenced" );
	}

	@Nonnull
	@Override
	default TextExpression get(@Nonnull TextAttribute<? super T> attribute) {
		throw new IllegalStateException( "Discriminator cannot be de-referenced" );
	}



	@Nonnull
	@SuppressWarnings({ "rawtypes", "unchecked" })
	@Override
	default SqmTreatedPath treatAs(@Nonnull Class treatJavaType) {
		throw new UnsupportedMappingException( "Cannot apply TREAT operator to discriminator path" );
	}

	@Nonnull
	@SuppressWarnings({ "rawtypes", "unchecked" })
	@Override
	default SqmTreatedPath treatAs(@Nonnull EntityDomainType treatTarget) {
		throw new UnsupportedMappingException( "Cannot apply TREAT operator to discriminator path" );
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	@Override
	@Nonnull
	default SqmTreatedPath treatAs(@Nonnull Class treatJavaType, @Nullable String alias) {
		throw new UnsupportedMappingException( "Cannot apply TREAT operator to discriminator path" );
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	@Override

View on GitHub (pinned to fad1729dce)

Solutions

  1. Apply TREAT to the entity path, not the discriminator: 'TREAT(p AS Employee)' / root.treatAs(Employee.class)
  2. Drop the nested treat entirely and query the subtype: 'from Employee e'
  3. If you meant to filter by subtype, use the discriminator comparison instead: where type(p) = Employee
  4. Audit generated/templated HQL for 'type(' followed by 'treat(' or '.treatAs(' on type() nodes

Example fix

-- before (HQL)
select treat(type(p) as Employee).salary from Person p
-- after
select treat(p as Employee).salary from Person p
Defensive patterns

Strategy: type-guard

Validate before calling

if (path instanceof DiscriminatorSqmPath) { /* skip treat, use type() = Class predicate instead */ } else { path.treatAs(Employee.class); }

Type guard

static boolean treatable(SqmPath<?> p) { return !(p instanceof org.hibernate.query.sqm.spi.DiscriminatorSqmPath); }

Try / catch

catch (UnsupportedMappingException e) { /* query rejected: apply treat to the entity root instead */ }

Prevention

When it happens

Trigger: HQL 'TREAT(type(p) AS Employee)' or Criteria 'root.type().treatAs(Employee.class)'. Also generic code that calls treatAs(...) on every SqmPath it visits while walking a query tree that contains a type() expression.

Common situations: Query-rewriting utilities (security filters, tenant filters, pagination wrappers) that inject treatAs calls into paths; teams migrating legacy HQL that mixed TYPE() and TREAT syntax after a Hibernate 6 upgrade; LLM- or template-generated HQL that nests treat inside type().

Related errors


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