{"record":{"id":"e61591bf3117d870","repo":"hibernate/hibernate-orm","slug":"could-not-interpret-attribute-s-of-basic-valued","errorCode":null,"errorMessage":"Could not interpret attribute '%s' of basic-valued path '%s'","messagePattern":"Could not interpret attribute '(.+?)' of basic-valued path '(.+?)'","errorType":"exception","errorClass":"UnknownPathException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/query/sqm/tree/spi/domain/SqmBasicValuedSimplePath.java","lineNumber":109,"sourceCode":"\t@Override\n\tpublic @Nonnull SqmBindableType<T> getExpressible() {\n\t\treturn this;\n\t}\n\n\t@Override\n\tpublic PersistenceType getPersistenceType() {\n\t\treturn BASIC;\n\t}\n\n\t// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\t// SemanticPathPart\n\n\t@Override\n\tpublic SqmPath<?> resolvePathPart(\n\t\t\tString name,\n\t\t\tboolean isTerminal,\n\t\t\tSqmCreationState creationState) {\n\t\tthrow new UnknownPathException(\n\t\t\t\tString.format(\n\t\t\t\t\t\t\"Could not interpret attribute '%s' of basic-valued path '%s'\",\n\t\t\t\t\t\tname, getNavigablePath()\n\t\t\t\t)\n\t\t);\n\t}\n\n\t@Override\n\tpublic SqmPath<?> resolveIndexedAccess(\n\t\t\tSqmExpression<?> selector,\n\t\t\tboolean isTerminal,\n\t\t\tSqmCreationState creationState) {\n\t\tfinal var pathRegistry =\n\t\t\t\tcreationState.getCurrentProcessingState().getPathRegistry();\n\t\tfinal String alias = selector.toHqlString();\n\t\tfinal NavigablePath navigablePath =\n\t\t\t\tgetParentNavigablePath().append( CollectionPart.Nature.ELEMENT.getName(), alias );\n\t\tfinal SqmFrom<?, ?> indexedPath = pathRegistry.findFromByPath( navigablePath );","sourceCodeStart":91,"sourceCodeEnd":127,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/spi/domain/SqmBasicValuedSimplePath.java#L91-L127","documentation":"Hibernate throws UnknownPathException from SqmBasicValuedSimplePath.resolvePathPart when HQL/JPQL path navigation tries to continue past an attribute that is a basic type (String, Integer, enum, converted object). A basic value has no sub-attributes, so the SQM semantic analyzer cannot resolve the requested attribute name on the path. The offending path part and the full navigable path are included in the message. The query fails at interpretation time, before any SQL is generated.","triggerScenarios":"Writing an HQL/JPQL query that dereferences a basic attribute, e.g. \"select e.name.foo from Employee e\" when e.name is a String; calling root.get(\"name\").get(\"x\") in the Criteria API; Spring Data JPA derived queries like findByName_Length where the property part is split into nested segments on a basic field; dynamic query builders appending segments to an already-basic path.","commonSituations":"A nested value object was mapped with an AttributeConverter (@Convert) instead of @Embedded, so the class is BASIC to Hibernate even though the developer thinks of it as structured; an attribute was renamed or moved during refactoring so the old path segment no longer resolves; Spring Data repository method names that accidentally split a single basic field name into multiple parts; copy-pasted queries from a different entity model.","solutions":["Remove or correct the trailing path segment so navigation stops at the basic attribute (use e.firstName, not e.name.firstName).","If the attribute is genuinely a structured object, map it as @Embeddable/@Embedded (or as an @OneToOne association) instead of a basic type with an AttributeConverter, then navigation will resolve.","If you wanted a String operation, use an HQL function (length(e.name), lower(e.name), substring(...)) instead of dot-path syntax.","Verify every path segment against the JPA metamodel or the entity class to catch typos before running the query."],"exampleFix":"// before - throws UnknownPathException if e.name is a basic String\nList<String> names = session.createQuery(\"select e.name.first from Employee e\", String.class).list();\n\n// after - navigate only while the type is embeddable/entity, stop at basic values\nList<String> names = session.createQuery(\"select e.name from Employee e\", String.class).list();","handlingStrategy":"validation","validationCode":"// Walk each path segment against the JPA metamodel before running the query\nstatic void assertNavigable(ManagedType<?> type, String... segments) {\n    for (int i = 0; i < segments.length; i++) {\n        Attribute<?, ?> attr = type.getAttribute(segments[i]);\n        if (i == segments.length - 1) return; // last segment: fine\n        if (!(attr instanceof SingularAttribute<?, ?> singular)\n                || !(singular.getType() instanceof ManagedType<?>)) {\n            throw new IllegalArgumentException(\n                \"Segment '\" + segments[i] + \"' is basic; cannot navigate to '\" + segments[i + 1] + \"'\");\n        }\n        type = (ManagedType<?>) singular.getType();\n    }\n}","typeGuard":"static boolean isBasicValued(ManagedType<?> owner, String attrName) {\n    Attribute<?, ?> a = owner.getAttribute(attrName);\n    return !(a instanceof SingularAttribute<?, ?> s) || !(s.getType() instanceof ManagedType<?>);\n}","tryCatchPattern":"try {\n    return session.createQuery(hql, type).list();\n} catch (org.hibernate.query.UnknownPathException e) {\n    throw new IllegalArgumentException(\"Invalid path in query: \" + hql + \" - \" + e.getMessage(), e);\n}","preventionTips":["Validate dynamically built HQL paths against the metamodel in development/profile mode.","Prefer @Embeddable over @Convert when a value object has fields you navigate to in queries.","Fail fast in tests: every query a repository layer can emit should have a unit test that parses it.","Log the exact HQL string when path resolution fails so the offending segment is obvious."],"tags":["hibernate","hql","jpql","sqm","path-navigation","criteria-api"],"backgroundTag":"hql-path-resolution-error","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}