{"record":{"id":"3e30e2ea1fd0bbf9","repo":"hibernate/hibernate-orm","slug":"could-not-resolve-attribute-s-of-s-due-to-th-3e30e2","errorCode":null,"errorMessage":"Could not resolve attribute '%s' of '%s' due to the attribute being declared in multiple subtypes '%s' and '%s'","messagePattern":"Could not resolve attribute '(.+?)' of '(.+?)' due to the attribute being declared in multiple subtypes '(.+?)' and '(.+?)'","errorType":"exception","errorClass":"PathException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java","lineNumber":6540,"sourceCode":"\t\t\t\t}\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\t}\n\n\tprivate ModelPart findSubPartInSubclassMappings(String name) {\n\t\tfinal var declaredGenericAttribute = declaredGenericAttributeMappings.get( name );\n\t\tif ( declaredGenericAttribute != null ) {\n\t\t\treturn declaredGenericAttribute;\n\t\t}\n\n\t\tModelPart attribute = null;\n\t\tif ( isNotEmpty( subclassMappingTypes ) ) {\n\t\t\tfor ( var subMappingType : subclassMappingTypes.values() ) {\n\t\t\t\tfinal var subDefinedAttribute = subMappingType.findSubTypesSubPart( name, null );\n\t\t\t\tif ( subDefinedAttribute != null ) {\n\t\t\t\t\tif ( attribute != null && !isCompatibleModelPart( attribute, subDefinedAttribute ) ) {\n\t\t\t\t\t\tthrow new PathException( String.format(\n\t\t\t\t\t\t\t\tLocale.ROOT,\n\t\t\t\t\t\t\t\t\"Could not resolve attribute '%s' of '%s' due to the attribute being declared in multiple subtypes '%s' and '%s'\",\n\t\t\t\t\t\t\t\tname,\n\t\t\t\t\t\t\t\tgetJavaType().getTypeName(),\n\t\t\t\t\t\t\t\tattribute.asAttributeMapping().getDeclaringType().getJavaType().getTypeName(),\n\t\t\t\t\t\t\t\tsubDefinedAttribute.asAttributeMapping().getDeclaringType().getJavaType().getTypeName()\n\t\t\t\t\t\t) );\n\t\t\t\t\t}\n\t\t\t\t\tattribute = subDefinedAttribute;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn attribute;\n\t}\n\n\t@Override\n\tpublic ModelPart findSubTypesSubPart(String name, EntityMappingType treatTargetType) {\n\t\tfinal var declaredAttribute = declaredAttributeMappings.get( name );","sourceCodeStart":6522,"sourceCodeEnd":6558,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java#L6522-L6558","documentation":"Thrown by AbstractEntityPersister.findSubPartInSubclassMappings while Hibernate resolves an attribute path (HQL, Criteria, or SQM navigation) against a polymorphic entity type. The lookup walks every subclass mapping type, and when two sibling subclasses each declare an attribute with the same name whose ModelParts are not compatible (different types or mappings), Hibernate cannot pick one unambiguously and throws a PathException naming both declaring classes. Attributes mapped once on a common root are found via declaredGenericAttributeMappings and never hit this conflict.","triggerScenarios":"Resolving a path like 'from Person p where p.alias = :x' on an inheritance root when 'alias' is declared separately (not inherited) in two subclasses with incompatible mappings; SQM findSubPart()/findSubTypesSubPart() calls during query translation, entity graphs, or Criteria attributes over a JOINED or union hierarchy with duplicated field names of different types.","commonSituations":"Copying a field into two sibling subclasses during refactoring; same-named columns with different types across union/implicit-polymorphism hierarchies; moving a field down from the superclass but leaving one subclass redeclaring it; dynamic-model or generic query builders hitting the root persister.","solutions":["Move the shared attribute onto the common superclass (or a @MappedSuperclass) so it is mapped exactly once","If the two attributes genuinely differ, rename one of them and update all queries","Query the concrete subclass that owns the attribute instead of the polymorphic root","If both must keep the name, make their mappings identical so isCompatibleModelPart() accepts the pair"],"exampleFix":"// before\n@Entity @Inheritance(strategy = JOINED)\nclass Person { }\nclass Author  extends Person { String alias; } // 'alias' declared here ...\nclass Editor extends Person { Integer alias; } // ... and here, incompatible type\n// 'from Person p where p.alias = :a' -> PathException\n\n// after\n@Entity @Inheritance(strategy = JOINED)\nclass Person { String alias; } // declared once on the root\nclass Author  extends Person { }\nclass Editor extends Person { }","handlingStrategy":"try-catch","validationCode":"Metamodel mm = sessionFactory.getMetamodel();\nEntityType<?> root = mm.entity(Person.class);\nint declared = 0;\nfor ( ManagedType<?> sub : mm.getSubtypes(root) ) {\n    try {\n        sub.getDeclaredAttribute(\"alias\");\n        declared++;\n    }\n    catch ( IllegalArgumentException notDeclaredHere ) { }\n}\nif ( declared > 1 ) {\n    // 'alias' is ambiguous across siblings: do not use it from the polymorphic root\n}","typeGuard":null,"tryCatchPattern":"try {\n    return session.createQuery(\"select p from Person p where p.alias = :a\", Person.class)\n                  .setParameter(\"a\", a)\n                  .list();\n}\ncatch ( org.hibernate.query.PathException e ) { // extends SemanticException; thrown at query creation\n    throw new IllegalArgumentException(\n        \"Attribute not uniquely resolvable across Person subtypes: \" + e.getMessage(), e );\n}","preventionTips":["Never declare the same attribute name in two sibling subclasses; move shared fields to the common root","Add a startup smoke test that compiles/creates every polymorphic query used in production","Review refactors that push fields down the hierarchy: one subclass still redeclaring the field is enough to trigger it"],"tags":["hibernate","orm","inheritance","hql","sqm","path-resolution","mapping"],"backgroundTag":"ambiguous-attribute-mapping","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}