hibernate/hibernate-orm · error · IllegalArgumentException

Not a treatable type: {}

Error message

Not a treatable type: {}

What it means

treatAs(Class) on a set join resolves the target Java type through the domain model with managedType(treatJavaType), then only accepts the treat if the resolved type is a TreatableDomainType (an entity or, in newer versions, a mapped superclass). If the class resolves to anything else — an interface grouping (polymorphic descriptor), an @Embeddable, or an unmapped class — Hibernate throws IllegalArgumentException naming the offending class.

Source

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

	}

	@Override
	@Nonnull
	public <S extends E> SqmTreatedSetJoin<O,E,S> treatAs(@Nonnull EntityDomainType<S> treatTarget, @Nullable String alias) {
		return treatAs( treatTarget, alias, false );
	}

	@Override
	@Nonnull
	public <S extends E> SqmTreatedSetJoin<O, E, S> treatAs(@Nonnull Class<S> treatJavaType, @Nullable String alias, boolean fetch) {
		final var treatTarget = nodeBuilder().getDomainModel().managedType( treatJavaType );
		final var treat = (SqmTreatedSetJoin<O, E, S>) findTreat( treatTarget, alias );
		if ( treat == null ) {
			if ( treatTarget instanceof TreatableDomainType<?> ) {
				return addTreat( new SqmTreatedSetJoin<>( this, (SqmTreatableDomainType<S>) treatTarget, alias, fetch ) );
			}
			else {
				throw new IllegalArgumentException( "Not a treatable type: " + treatJavaType.getName() );
			}
		}
		else {
			return treat;
		}
	}

	@Override
	@Nonnull
	public <S extends E> SqmTreatedSetJoin<O,E,S> treatAs(@Nonnull EntityDomainType<S> treatTarget, @Nullable String alias, boolean fetch) {
		final var treat = (SqmTreatedSetJoin<O, E, S>) findTreat( treatTarget, alias );
		if ( treat == null ) {
			return addTreat( new SqmTreatedSetJoin<>( this, (SqmEntityDomainType<S>) treatTarget, alias, fetch ) );
		}
		else {
			return treat;
		}
	}

View on GitHub (pinned to fad1729dce)

Solutions

  1. Treat to a concrete @Entity subtype of the joined element type: join.treat(CreditCardPayment.class).
  2. Verify the target is mapped: metamodel.entity(target) must succeed (and be a subtype of the join element type) before calling treat.
  3. If the target is an interface, treat each implementor separately or drop the treat and rely on implicit polymorphism with instanceof filtering.
  4. Use the treatAs(EntityDomainType) overload after resolving metamodel.entity(target) so mapping errors surface earlier and clearer.

Example fix

// before
SetJoin<Order, BillingDetails> details = root.joinSet("billingDetails");
details.treat(OnlinePayment.class); // OnlinePayment is an interface -> Not a treatable type
// after
details.treat(CreditCardPayment.class); // concrete @Entity subtype
// or resolve first:
EntityDomainType<CreditCardPayment> target = sf.getJpaMetamodel().entity(CreditCardPayment.class);
details.treatAs(target);
Defensive patterns

Strategy: validation

Validate before calling

static boolean isTreatableTarget(EntityManagerFactory emf, Class<?> joinedType, Class<?> target) {
    try {
        jakarta.persistence.metamodel.EntityType<?> e = emf.getMetamodel().entity(target); // real entity only
        return joinedType.isAssignableFrom(target);
    } catch (IllegalArgumentException notMapped) {
        return false; // interface/embeddable/unmapped -> treat would throw
    }
}

Type guard

static boolean treatable(EntityManagerFactory emf, Class<?> target) {
    try { emf.getMetamodel().entity(target); return true; }
    catch (IllegalArgumentException e) { return false; }
}

Try / catch

try {
    treated = setJoin.treat(targetClass);
} catch (IllegalArgumentException e) {
    if (e.getMessage() != null && e.getMessage().startsWith("Not a treatable type")) {
        // fall back: query concrete implementors separately
    } else throw e;
}

Prevention

When it happens

Trigger: Calling setJoin.treat(SomeInterface.class) where SomeInterface is implemented by several entities (managedType returns SqmPolymorphicRootDescriptor, not treatable); treating to an @Embeddable target; treating to a class not included in the persistence unit.

Common situations: Criteria/HQL TREAT on collection joins whose element type is an interface; refactors where the treat target stopped being an @Entity (annotation lost, class moved to another module); typo'd or unmapped subclass names in treatAs.

Related errors


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