hibernate/hibernate-orm · error · TreatException

Embeddable paths cannot be TREAT-ed

Error message

Embeddable paths cannot be TREAT-ed

What it means

SqmFunctionPath rejects TREAT with TreatException: when the function result is embeddable-valued, treating it to an entity type is meaningless (embeddables have no inheritance or identity), so treatAs(Class) throws. Unlike SqmEmbeddedValuedSimplePath, the function path has no embeddable-treat delegation at all.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/query/sqm/tree/spi/domain/SqmFunctionPath.java:161

		final SqmFunctionPath<?> path = new SqmFunctionPath<>( result );
		pathRegistry.register( path );
		return path;
	}

	@Override
	public <X> X accept(SemanticQueryWalker<X> walker) {
		return walker.visitFunctionPath( this );
	}

	@Override
	public void appendHqlString(StringBuilder hql, SqmRenderContext context) {
		function.appendHqlString( hql, context );
	}

	@Nonnull
	@Override
	public <S extends T> SqmTreatedPath<T,S> treatAs(@Nonnull Class<S> treatJavaType) {
		throw new TreatException( "Embeddable paths cannot be TREAT-ed" );
	}

	@Nonnull
	@Override
	public <S extends T> SqmTreatedPath<T,S> treatAs(@Nonnull EntityDomainType<S> treatTarget) {
		throw new TreatException( "Embeddable paths cannot be TREAT-ed" );
	}

	@Override
	public boolean equals(@Nullable Object object) {
		return super.equals( object )
			&& function.equals( ((SqmFunctionPath<?>) object).function );
	}

	@Override
	public int hashCode() {
		int result = super.hashCode();
		result = 31 * result + function.hashCode();

View on GitHub (pinned to fad1729dce)

Solutions

  1. Drop the TREAT and navigate the embeddable's attributes directly from the function result (f(a).subAttr)
  2. If polymorphism is required, make the function return an entity type and use it as a function root instead of a path
  3. Verify the target class: if it is an @Embeddable you may not treat at all on function paths; if it is an @Entity the whole construct is invalid here

Example fix

// before: address_of() returns an embeddable; USAddress is an @Entity
select treat(address_of(p) as USAddress).zip from Person p

// after: navigate the embeddable result directly
select address_of(p).zip from Person p
Defensive patterns

Strategy: type-guard

Type guard

static boolean supportsTreatToEntity(SqmPath<?> p) {
    return !(p instanceof SqmFunctionPath<?>)
        && !(p instanceof SqmFkExpression<?>)
        && p.getReferencedPathSource().getPathType() instanceof IdentifiableDomainType<?>;
}

Try / catch

try {
    treated = functionPath.treatAs(targetClass);
} catch (TreatException e) {
    // embeddable-valued function result: navigate attributes directly instead of treating
    throw new IllegalStateException("Function paths cannot be TREAT-ed; navigate f().attr directly", e);
}

Prevention

When it happens

Trigger: HQL 'treat(f(a) as SomeEntity)' where f returns an embeddable; criteria calling functionPath.treatAs(SomeEntity.class) on a navigable function result over an embeddable type.

Common situations: Structured function results (e.g. functions returning a mapped embeddable) that developers try to downcast; mixing up entity and embeddable targets when reusing TREAT snippets; generic query DSLs that attach treatAs to every path.

Related errors


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