hibernate/hibernate-orm · error · UnknownPathException

Static enum reference [%s#%s] cannot be de-referenced

Error message

Static enum reference [%s#%s] cannot be de-referenced

What it means

An enum literal in HQL ('MyEnum.CONSTANT') compiles to SqmEnumLiteral, a leaf node holding the enum value and its descriptor. Enum literals expose no navigable members, so attribute navigation off the literal — resolvePathPart — throws UnknownPathException('Static enum reference [FQN#CONSTANT] cannot be de-referenced').

Source

Thrown at hibernate-core/src/main/java/org/hibernate/query/sqm/tree/spi/expression/SqmEnumLiteral.java:110

	public EnumJavaType<E> getExpressibleJavaType() {
		return referencedEnumTypeDescriptor;
	}

	@Override
	public Class<E> getJavaType() {
		return referencedEnumTypeDescriptor.getJavaTypeClass();
	}


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

	@Override
	public SemanticPathPart resolvePathPart(
			String name,
			boolean isTerminal,
			SqmCreationState creationState) {
		throw new UnknownPathException(
				String.format(
						Locale.ROOT,
						"Static enum reference [%s#%s] cannot be de-referenced",
						referencedEnumTypeDescriptor.getTypeName(),
						enumValueName
				)
		);
	}

	@Override
	public SqmPath<?> resolveIndexedAccess(
			SqmExpression<?> selector,
			boolean isTerminal,
			SqmCreationState creationState) {
		throw new UnknownPathException(
				String.format(
						Locale.ROOT,
						"Static enum reference [%s#%s] cannot be de-referenced",

View on GitHub (pinned to fad1729dce)

Solutions

  1. Bind the derived value as a parameter: 'where o.code = :code' with query.setParameter("code", Status.APPROVED.getCode()).
  2. Compare against the enum itself: 'where o.status = Status.APPROVED' (with @Enumerated mapping).
  3. If the enum field is mapped on the entity, filter on the entity attribute, not on the literal.
  4. For code/label tables, join the lookup table instead of dereferencing the enum literal.

Example fix

-- before (HQL)
from Order o where o.statusCode = StatusCode.APPROVED.code
-- after
from Order o where o.statusCode = :code
// Java: query.setParameter("code", StatusCode.APPROVED.getCode())
Defensive patterns

Strategy: try-catch

Validate before calling

// Lint HQL: enum constant followed by another member (Enum.CONSTANT.member) is invalid
static boolean hqlDereferencesEnumLiteral(String hql) {
    return hql.matches("(?s).*\\b[A-Z]\\w*\\.[A-Z][A-Z0-9_]*\\.[a-zA-Z]\\w*.*");
}

Try / catch

try {
    return em.createQuery(hql, resultClass);
} catch (UnknownPathException badPath) { // org.hibernate.query.UnknownPathException
    throw new IllegalArgumentException("Enum literal dereferenced in query: " + hql, badPath);
}

Prevention

When it happens

Trigger: HQL like 'where o.code = Status.APPROVED.code' or 'select Status.APPROVED.label from Order o' — any dot-navigation off an enum constant; also 'on' clauses and order-by fragments appending members to enum literals.

Common situations: Enums carrying extra fields (code, label, externalId) where the query tries to compare against the field instead of the enum itself; refactor of numeric status columns into enums; string-built HQL that appends attribute names to literals.

Related errors


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