hibernate/hibernate-orm · error · UnknownPathException

Could not interpret attribute '%s' of basic-valued path '%s'

Error message

Could not interpret attribute '%s' of basic-valued path '%s'

What it means

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.

Source

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

	@Override
	public @Nonnull SqmBindableType<T> getExpressible() {
		return this;
	}

	@Override
	public PersistenceType getPersistenceType() {
		return BASIC;
	}

	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// SemanticPathPart

	@Override
	public SqmPath<?> resolvePathPart(
			String name,
			boolean isTerminal,
			SqmCreationState creationState) {
		throw new UnknownPathException(
				String.format(
						"Could not interpret attribute '%s' of basic-valued path '%s'",
						name, getNavigablePath()
				)
		);
	}

	@Override
	public SqmPath<?> resolveIndexedAccess(
			SqmExpression<?> selector,
			boolean isTerminal,
			SqmCreationState creationState) {
		final var pathRegistry =
				creationState.getCurrentProcessingState().getPathRegistry();
		final String alias = selector.toHqlString();
		final NavigablePath navigablePath =
				getParentNavigablePath().append( CollectionPart.Nature.ELEMENT.getName(), alias );
		final SqmFrom<?, ?> indexedPath = pathRegistry.findFromByPath( navigablePath );

View on GitHub (pinned to fad1729dce)

Solutions

  1. Remove or correct the trailing path segment so navigation stops at the basic attribute (use e.firstName, not e.name.firstName).
  2. 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.
  3. If you wanted a String operation, use an HQL function (length(e.name), lower(e.name), substring(...)) instead of dot-path syntax.
  4. Verify every path segment against the JPA metamodel or the entity class to catch typos before running the query.

Example fix

// before - throws UnknownPathException if e.name is a basic String
List<String> names = session.createQuery("select e.name.first from Employee e", String.class).list();

// after - navigate only while the type is embeddable/entity, stop at basic values
List<String> names = session.createQuery("select e.name from Employee e", String.class).list();
Defensive patterns

Strategy: validation

Validate before calling

// Walk each path segment against the JPA metamodel before running the query
static void assertNavigable(ManagedType<?> type, String... segments) {
    for (int i = 0; i < segments.length; i++) {
        Attribute<?, ?> attr = type.getAttribute(segments[i]);
        if (i == segments.length - 1) return; // last segment: fine
        if (!(attr instanceof SingularAttribute<?, ?> singular)
                || !(singular.getType() instanceof ManagedType<?>)) {
            throw new IllegalArgumentException(
                "Segment '" + segments[i] + "' is basic; cannot navigate to '" + segments[i + 1] + "'");
        }
        type = (ManagedType<?>) singular.getType();
    }
}

Type guard

static boolean isBasicValued(ManagedType<?> owner, String attrName) {
    Attribute<?, ?> a = owner.getAttribute(attrName);
    return !(a instanceof SingularAttribute<?, ?> s) || !(s.getType() instanceof ManagedType<?>);
}

Try / catch

try {
    return session.createQuery(hql, type).list();
} catch (org.hibernate.query.UnknownPathException e) {
    throw new IllegalArgumentException("Invalid path in query: " + hql + " - " + e.getMessage(), e);
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


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