hibernate/hibernate-orm · error · UnknownEntityException

Could not resolve target entity

Error message

Could not resolve target entity '${entityName}'

What it means

visitEntityName resolves a name that must denote an entity (treat(x as N), type comparisons, entity joins, etc.) through JpaMetamodel.getHqlEntityReference. A null result means no entity or registered polymorphic reference answers to that name, so UnknownEntityException is thrown carrying the unresolved name.

Solutions

  1. List the accepted names via em.getMetamodel().getEntities() and use the exact mapped name (mind case and quoting)
  2. Check for @Entity(name=...) overrides and match that name
  3. Ensure the entity is in the same persistence unit and picked up by scanning
  4. For treat/type targets, verify the subclass is a mapped entity, not just a Java class

Example fix

// before
select treat(o as SpecialOrder) from Order o  // SpecialOrder not mapped

// after
select treat(o as SpecialOrder) from Order o  // after adding @Entity to SpecialOrder and refreshing the SessionFactory
Defensive patterns

Strategy: validation

Validate before calling

static boolean isMappedEntityName(EntityManagerFactory emf, String name) {
    for (jakarta.persistence.metamodel.EntityType<?> e : emf.getMetamodel().getEntities()) {
        if (e.getName().equals(name)) return true;
    }
    return false;
}

// before building the query
if (!isMappedEntityName(emf, entityName)) throw new IllegalArgumentException("Unknown entity name: " + entityName);

Type guard

static boolean isUnknownEntity(Throwable t) {
    return t instanceof org.hibernate.query.sqm.UnknownEntityException;
}

Try / catch

try {
    return em.createQuery(hql, Object.class).getResultList();
} catch (org.hibernate.query.sqm.UnknownEntityException e) {
    // e.getEntityName() carries the unresolved name
    throw new IllegalArgumentException("Entity not found in this persistence unit: " + e.getEntityName(), e);
}

Prevention

When it happens

Trigger: 'select treat(o as SpecialOrder) from Order o' when SpecialOrder is not a mapped entity; 'where type(a) = MissingEntity'; using a DTO, interface or enum class name in a position that requires an entity name.

Common situations: Typos or wrong case (the mapped name differs from the simple class name or @Entity(name=...) is set); entity lives in another persistence unit; class renamed during refactoring; using the FQN where only the unqualified name is registered.

Related errors


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

Appendix: source

Thrown at hibernate-core/src/main/java/org/hibernate/query/hql/internal/SemanticQueryBuilder.java:2036

				? child.getText()
				: visitNakedIdentifier( (HqlParser.NakedIdentifierContext) child );
	}

	@Override
	public String visitNakedIdentifier(HqlParser.NakedIdentifierContext ctx) {
		final var node = (TerminalNode) ctx.getChild( 0 );
		final String text = node.getText();
		return node.getSymbol().getType() == QUOTED_IDENTIFIER
				? unquoteIdentifier( text )
				: text;
	}

	@Override
	public EntityDomainType<?> visitEntityName(HqlParser.EntityNameContext parserEntityName) {
		final String entityName = getEntityName( parserEntityName );
		final var entityReference = getJpaMetamodel().getHqlEntityReference( entityName );
		if ( entityReference == null ) {
			throw new UnknownEntityException( "Could not resolve target entity '" + entityName + "'", entityName );
		}
		checkFQNEntityNameJpaComplianceViolationIfNeeded( entityName, entityReference );
		if ( entityReference instanceof SqmPolymorphicRootDescriptor<?>
				&& getCreationOptions().useStrictJpaCompliance() ) {
			throw new StrictJpaComplianceViolation(
					"Encountered the use of a non entity name [" + entityName + "], " +
							"but strict JPQL compliance was requested which doesn't allow this",
					StrictJpaComplianceViolation.Type.NON_ENTITY_NAME
			);
		}
		return entityReference;
	}

	@Override
	public SqmFromClause visitFromClause(HqlParser.FromClauseContext parserFromClause) {
		final var roots = parserFromClause.entityWithJoins();
		final var fromClause = new SqmFromClause( roots.size() );

View on GitHub (pinned to fad1729dce)