hibernate/hibernate-orm · error · HqlInterpretationException

Cannot dereference an entity name

Error message

Cannot dereference an entity name

What it means

SqmAnyDiscriminatorValue is the SQM node produced by HQL TYPE(e) — it represents an entity name token from the discriminator, not a path. Because an entity name has no members, resolvePathPart (attribute navigation like 'type(p).name') throws HqlInterpretationException('Cannot dereference an entity name') at query interpretation time.

Source

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

	public EntityDomainType getEntityValue() {
		return value;
	}

	public String getPathName() {
		return pathName;
	}

	@Override
	public String asLoggableText() {
		return getEntityValue().getName();
	}

	@Override
	public SemanticPathPart resolvePathPart(
			String name,
			boolean isTerminal,
			SqmCreationState creationState) {
		throw new HqlInterpretationException( "Cannot dereference an entity name" );
	}

	@Override
	public SqmPath<?> resolveIndexedAccess(
			SqmExpression<?> selector,
			boolean isTerminal,
			SqmCreationState creationState) {
		throw new HqlInterpretationException( "Cannot dereference an entity name" );
	}

	@Override
	public void appendHqlString(StringBuilder hql, SqmRenderContext context) {
		hql.append( getEntityValue().getName() );
	}

	@Override
	public boolean equals(@Nullable Object object) {
		return object instanceof SqmAnyDiscriminatorValue<?> that

View on GitHub (pinned to fad1729dce)

Solutions

  1. Use the type token whole: 'select type(p) from Payment p' or compare it directly: 'where type(p) = CreditCardPayment'.
  2. To get the name as a string, materialize the entity and use getClass().getName()/getEntityName() in Java, or select the discriminator column via native/typed projection if the mapping exposes it.
  3. For per-subtype logic use TREAT AS or separate queries per concrete type.
  4. Fix dynamic query builders to never append attribute paths to non-path expressions like TYPE(...).

Example fix

-- before (HQL)
select type(p).name from Payment p  -- cannot dereference an entity name
-- after
select type(p) from Payment p  -- use the token itself
-- or: select p from Payment p where type(p) = CreditCardPayment
Defensive patterns

Strategy: try-catch

Validate before calling

// Lint dynamically built HQL: TYPE(...) must not be followed by '.' or '['
static boolean hqlDereferencesType(String hql) {
    return hql.matches("(?is).*type\\s*\\([^)]*\\)\\s*(\\.|\\[).*");
}

Try / catch

try {
    return em.createQuery(hql, resultClass);
} catch (HqlInterpretationException badPath) {
    throw new IllegalArgumentException("Query dereferences an entity name (TYPE(...).attr): " + hql, badPath);
}

Prevention

When it happens

Trigger: HQL that dots into a TYPE() expression: 'select type(p).name from Payment p', 'where type(p).id = 1', or any path continuation after type(...); criteria code that calls .get(...) on the expression returned by cb.type(path).

Common situations: Developers expecting TYPE(e) to return a string-like value they can select parts of; dynamic query builders that concatenate '.x' onto arbitrary expressions; migrating queries that used discriminators as strings in Hibernate 5 HQL.

Related errors


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