{"record":{"id":"eee1dbe05d7161ff","repo":"hibernate/hibernate-orm","slug":"non-jpa-classification","errorCode":null,"errorMessage":"Non-JPA classification: {}","messagePattern":"Non-JPA classification: (.+?)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/AbstractAttribute.java","lineNumber":107,"sourceCode":"\n\t@Override\n\t@Nonnull\n\tpublic Member getJavaMember() {\n\t\treturn member;\n\t}\n\n\t@Override\n\t@Nonnull\n\tpublic AttributeClassification getAttributeClassification() {\n\t\treturn attributeClassification;\n\t}\n\n\t@Override\n\t@Nonnull\n\tpublic PersistentAttributeType getPersistentAttributeType() {\n\t\tfinal var classification = getAttributeClassification().getJpaClassification();\n\t\tif ( classification == null ) {\n\t\t\tthrow new IllegalStateException( \"Non-JPA classification: \" + attributeClassification );\n\t\t}\n\t\treturn classification;\n\t}\n\n\t@Override\n\t@Nonnull\n\tpublic DomainType<?> getValueGraphType() {\n\t\treturn valueType;\n\t}\n\n\tNavigablePath getParentNavigablePath(SqmPath<?> parent) {\n\t\tfinal var parentPathSource = parent.getResolvedModel();\n\t\tfinal var parentType = parentPathSource.getPathType();\n\t\tfinal var parentNavigablePath = buildParentNavigablePath( parent, \"\" );\n\t\tif ( parentType != declaringType\n\t\t\t\t&& parentType instanceof EntityDomainType<?> entityDomainType\n\t\t\t\t&& entityDomainType.findAttribute( name ) == null ) {\n\t\t\t// If the parent path is an entity type which does not contain the","sourceCodeStart":89,"sourceCodeEnd":125,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/AbstractAttribute.java#L89-L125","documentation":"Hibernate's JPA metamodel attribute implementation cannot return a javax.persistence PersistentAttributeType because the attribute's Hibernate-specific AttributeClassification has no JPA equivalent. The only classification that maps to null is ANY (see AttributeClassification.getJpaClassification(), which returns null for ANY). Calling getPersistentAttributeType() on such an attribute therefore violates the JPA contract and Hibernate throws IllegalStateException.","triggerScenarios":"Calling attribute.getPersistentAttributeType() on an attribute mapped with @Any / @AnyDiscriminator / hbm <any/> (AttributeClassification.ANY). Typically reached via the Criteria/JPA metamodel API, e.g. managedType.getAttributes().stream().map(a -> a.getPersistentAttributeType()), or via code that switches on PersistentAttributeType for every attribute of an entity.","commonSituations":"Entities using @Any polymorphic references (a column holding a discriminator plus a foreign key to any of several entities). Generic frameworks or utility code that walks the metamodel and assumes every attribute has a JPA classification. Migrating from Hibernate 5 where metamodel internals differed.","solutions":["Filter or branch on @Any-mapped attributes before calling getPersistentAttributeType(); use Hibernate's extended API getAttributeClassification() instead, which returns ANY","Replace @Any mapping with a regular @ManyToOne to a common supertype or a join table if the JPA metamodel must be fully walkable","Guard the call: if (attribute instanceof HibernateAttribute ha && ha.getAttributeClassification() == AttributeClassification.ANY) skip it"],"exampleFix":"// before\nfor (Attribute<?,?> a : managedType.getAttributes()) {\n    PersistentAttributeType t = a.getPersistentAttributeType(); // throws for @Any\n}\n\n// after\nfor (Attribute<?,?> a : managedType.getAttributes()) {\n    if (a.getPersistentAttributeType() == null) continue; // never reached; use try/catch or\n    if (a instanceof SingularAttribute<?,?> sa && \"org.hibernate.metamodel.model.domain.SqmPathSource\".isInstance(a)) {\n        // Hibernate extension: check classification first\n    }\n    PersistentAttributeType t = a.getPersistentAttributeType();\n}","handlingStrategy":"type-guard","validationCode":"// Before iterating, filter attributes by Hibernate's extended classification\nimport org.hibernate.metamodel.AttributeClassification;\n\nfor (Attribute<?,?> a : managedType.getAttributes()) {\n    if (a instanceof org.hibernate.metamodel.model.domain.internal.AbstractAttribute<?,?,?> hib\n            && hib.getAttributeClassification() == AttributeClassification.ANY) {\n        continue; // @Any attribute: no JPA PersistentAttributeType\n    }\n    PersistentAttributeType t = a.getPersistentAttributeType();\n}","typeGuard":"static boolean hasJpaClassification(Attribute<?,?> a) {\n    return a instanceof org.hibernate.metamodel.model.domain.internal.AbstractAttribute<?,?,?> hib\n        && hib.getAttributeClassification().getJpaClassification() != null;\n}","tryCatchPattern":"try {\n    PersistentAttributeType t = attr.getPersistentAttributeType();\n} catch (IllegalStateException e) {\n    if (e.getMessage() != null && e.getMessage().startsWith(\"Non-JPA classification\")) {\n        // @Any-mapped attribute: handle via Hibernate-specific classification\n        continue;\n    }\n    throw e;\n}","preventionTips":["Prefer Hibernate's getAttributeClassification() over the JPA getPersistentAttributeType() in generic metamodel code","Document which entities use @Any so framework code can special-case them","Write one integration test that walks every entity's attributes through your metamodel utilities"],"tags":["hibernate","jpa-metamodel","any-mapping","illegal-state"],"backgroundTag":"jpa-metamodel-attribute-type","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}