hibernate/hibernate-orm · error · UnknownEntityTypeException

Unknown entity type '{}'

Error message

Unknown entity type '{}'

What it means

The three-argument createNativeQuery(sql, resultClass, tableAlias) overload has entity semantics: it binds resultClass as a mapped entity under the alias (addEntity(alias, resultClass, LockMode.READ)). getMappingMetamodel().isEntityClass(resultClass) is false for DTOs, records, interfaces, and mapped superclasses, so UnknownEntityTypeException('Unknown entity type <class>') is thrown.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/internal/AbstractSharedSessionContract.java:1965

					: null,
				resultClass
		);
	}

	@Override
	@Nonnull
	public <T> NativeQueryImplementor<T> createNativeQuery(
			@Nonnull String sqlString,
			@Nonnull Class<T> resultClass,
			@Nonnull String tableAlias) {
		checksBeforeQueryCreation();
		final var query = buildNativeQuery( sqlString, null, resultClass );
		if ( getMappingMetamodel().isEntityClass( resultClass ) ) {
			query.addEntity( tableAlias, resultClass, LockMode.READ );
			return query;
		}
		else {
			throw new UnknownEntityTypeException( resultClass );
		}
	}

	private <T> NativeQueryImpl<T> buildNativeQuery(
			String sql,
			@Nullable NamedResultSetMappingMemento resultSetMapping,
			@Nullable Class<T> resultClass) {
		try {
			final var query = new NativeQueryImpl<>( sql, resultSetMapping, resultClass, this );
			if ( isEmpty( query.getComment() ) ) {
				query.setComment( "dynamic native SQL query" );
			}
			applyQuerySettingsAndHints( query );
			return query;
		}
		catch ( RuntimeException he ) {
			throw getExceptionConverter().convert( he );
		}

View on GitHub (pinned to fad1729dce)

Solutions

  1. For DTO projections drop the alias argument: createNativeQuery(sql, CustomerDto.class) — Hibernate maps columns to the DTO by position/name.
  2. If you meant an entity, pass the mapped @Entity class (the concrete leaf for inheritance).
  3. Alternatively define the mapping explicitly with @SqlResultSetMapping and use the mapping-name overload.

Example fix

// before
NativeQuery<CustomerDto> q = session.createNativeQuery(
    "select id, name from customer c", CustomerDto.class, "c"); // UnknownEntityTypeException
// after (DTO projection: two-arg form)
NativeQuery<CustomerDto> q = session.createNativeQuery(
    "select id, name from customer", CustomerDto.class);
Defensive patterns

Strategy: type-guard

Type guard

static boolean isMappedEntity(SessionFactory sf, Class<?> type) {
    return sf.getMetamodel().getEntities().stream()
             .anyMatch(e -> type.equals(e.getJavaType()));
}

// usage: choose the right native-query overload
if (isMappedEntity(sf, resultClass)) {
    return session.createNativeQuery(sql, resultClass, alias); // entity binding
} else {
    return session.createNativeQuery(sql, resultClass);         // DTO projection
}

Prevention

When it happens

Trigger: createNativeQuery(sql, CustomerDto.class, "c") where CustomerDto is a projection DTO; passing a base class or @MappedSuperclass of the entity; interface-typed results — anything that is not a registered @Entity in the mapping metamodel.

Common situations: Switching a two-argument native DTO query to the three-arg form after an IDE suggestion or Hibernate 5 addEntity-style port; projection interfaces/records used with the alias overload; inheritance hierarchies queried with the root abstract class.

Related errors


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