{"record":{"id":"6327c5721408e98a","repo":"hibernate/hibernate-orm","slug":"not-a-treatable-type-6327c5","errorCode":null,"errorMessage":"Not a treatable type: {}","messagePattern":"Not a treatable type: (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/query/sqm/tree/spi/domain/SqmSetJoin.java","lineNumber":170,"sourceCode":"\t}\n\n\t@Override\n\t@Nonnull\n\tpublic <S extends E> SqmTreatedSetJoin<O,E,S> treatAs(@Nonnull EntityDomainType<S> treatTarget, @Nullable String alias) {\n\t\treturn treatAs( treatTarget, alias, false );\n\t}\n\n\t@Override\n\t@Nonnull\n\tpublic <S extends E> SqmTreatedSetJoin<O, E, S> treatAs(@Nonnull Class<S> treatJavaType, @Nullable String alias, boolean fetch) {\n\t\tfinal var treatTarget = nodeBuilder().getDomainModel().managedType( treatJavaType );\n\t\tfinal var treat = (SqmTreatedSetJoin<O, E, S>) findTreat( treatTarget, alias );\n\t\tif ( treat == null ) {\n\t\t\tif ( treatTarget instanceof TreatableDomainType<?> ) {\n\t\t\t\treturn addTreat( new SqmTreatedSetJoin<>( this, (SqmTreatableDomainType<S>) treatTarget, alias, fetch ) );\n\t\t\t}\n\t\t\telse {\n\t\t\t\tthrow new IllegalArgumentException( \"Not a treatable type: \" + treatJavaType.getName() );\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\treturn treat;\n\t\t}\n\t}\n\n\t@Override\n\t@Nonnull\n\tpublic <S extends E> SqmTreatedSetJoin<O,E,S> treatAs(@Nonnull EntityDomainType<S> treatTarget, @Nullable String alias, boolean fetch) {\n\t\tfinal var treat = (SqmTreatedSetJoin<O, E, S>) findTreat( treatTarget, alias );\n\t\tif ( treat == null ) {\n\t\t\treturn addTreat( new SqmTreatedSetJoin<>( this, (SqmEntityDomainType<S>) treatTarget, alias, fetch ) );\n\t\t}\n\t\telse {\n\t\t\treturn treat;\n\t\t}\n\t}","sourceCodeStart":152,"sourceCodeEnd":188,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/spi/domain/SqmSetJoin.java#L152-L188","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Treat to a concrete @Entity subtype of the joined element type: join.treat(CreditCardPayment.class).","Verify the target is mapped: metamodel.entity(target) must succeed (and be a subtype of the join element type) before calling treat.","If the target is an interface, treat each implementor separately or drop the treat and rely on implicit polymorphism with instanceof filtering.","Use the treatAs(EntityDomainType) overload after resolving metamodel.entity(target) so mapping errors surface earlier and clearer."],"exampleFix":"// before\nSetJoin<Order, BillingDetails> details = root.joinSet(\"billingDetails\");\ndetails.treat(OnlinePayment.class); // OnlinePayment is an interface -> Not a treatable type\n// after\ndetails.treat(CreditCardPayment.class); // concrete @Entity subtype\n// or resolve first:\nEntityDomainType<CreditCardPayment> target = sf.getJpaMetamodel().entity(CreditCardPayment.class);\ndetails.treatAs(target);","handlingStrategy":"validation","validationCode":"static boolean isTreatableTarget(EntityManagerFactory emf, Class<?> joinedType, Class<?> target) {\n    try {\n        jakarta.persistence.metamodel.EntityType<?> e = emf.getMetamodel().entity(target); // real entity only\n        return joinedType.isAssignableFrom(target);\n    } catch (IllegalArgumentException notMapped) {\n        return false; // interface/embeddable/unmapped -> treat would throw\n    }\n}","typeGuard":"static boolean treatable(EntityManagerFactory emf, Class<?> target) {\n    try { emf.getMetamodel().entity(target); return true; }\n    catch (IllegalArgumentException e) { return false; }\n}","tryCatchPattern":"try {\n    treated = setJoin.treat(targetClass);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage() != null && e.getMessage().startsWith(\"Not a treatable type\")) {\n        // fall back: query concrete implementors separately\n    } else throw e;\n}","preventionTips":["Treat only to concrete @Entity subtypes of the joined element type.","Pre-resolve targets with metamodel.entity(...) and pass the EntityDomainType overload of treatAs.","Keep a startup check that validates all treat targets used by query builders.","For interface targets, write one query per implementor and union results."],"tags":["hibernate","criteria-api","treat","jpa-metamodel","illegal-argument","downcasting"],"backgroundTag":"invalid-treat-target","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}