hibernate/hibernate-orm · error · QueryTypeMismatchException

Incorrect query result type: query produces '%s' but type '%

Error message

Incorrect query result type: query produces '%s' but type '%s' was given

What it means

Typed query creation (createSelectionQuery/createQuery with an expected result class) calls checkResultType(): the query's actual result type must be assignable to the requested class, otherwise QueryTypeMismatchException('Incorrect query result type: query produces X but type Y was given'). It enforces the contract between the HQL select list and the Java type before execution.

Source

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

	protected HqlInterpretation<?> interpretHql(String hql) {
		return interpretHql( hql, null );
	}

	protected <R> HqlInterpretation<R> interpretHql(String hql, Class<R> resultType) {
		return getFactory().getQueryEngine().interpretHql( hql, resultType );
	}

	protected static void checkSelectionQuery(String hql, HqlInterpretation<?> hqlInterpretation) {
		if ( !( hqlInterpretation.getSqmStatement() instanceof SqmSelectStatement ) ) {
			throw new IllegalSelectQueryException( "Expecting a selection query, but found '" + hql + "'", hql);
		}
	}

	protected static <R> void checkResultType(Class<R> expectedResultType, SelectionQuery<R> query) {
		final var resultType = query.getResultType();
		if ( !expectedResultType.isAssignableFrom( resultType ) ) {
			throw new QueryTypeMismatchException(
					String.format(
							Locale.ROOT,
							"Incorrect query result type: query produces '%s' but type '%s' was given",
							expectedResultType.getName(),
							resultType.getName()
					)
			);
		}
	}

	protected NamedResultSetMappingMemento getResultSetMappingMemento(String resultSetMappingName) {
		final var resultSetMappingMemento =
				namedObjectRepository().getResultSetMappingMemento( resultSetMappingName );
		if ( resultSetMappingMemento == null ) {
			throw new HibernateException( "No result set mapping with given name '" + resultSetMappingName + "'" );
		}
		return resultSetMappingMemento;
	}

View on GitHub (pinned to fad1729dce)

Solutions

  1. Match the class to the select list: counts are Long.class; multi-column selects need Object[]/Tuple/the exact DTO class.
  2. Adjust the HQL select clause to produce the requested shape (e.g., select new com.Dto(a.id, a.name)).
  3. Create the query untyped and map results manually when shapes vary at runtime.

Example fix

// before
Long n = session.createQuery("select count(u) from User u", Integer.class).getSingleResult();
// QueryTypeMismatchException: query produces java.lang.Long
// after
Long n = session.createQuery("select count(u) from User u", Long.class).getSingleResult();
Defensive patterns

Strategy: validation

Validate before calling

// Create untyped first, inspect the real result type, then act
SelectionQuery<?> raw = session.createSelectionQuery(hql);
Class<?> actual = raw.getResultType();
if (!expectedType.isAssignableFrom(actual)) {
    throw new IllegalArgumentException(
        "HQL produces " + actual.getName() + "; caller expected " + expectedType.getName());
}
@SuppressWarnings("unchecked")
SelectionQuery<T> typed = (SelectionQuery<T>) raw;

Try / catch

try {
    return session.createSelectionQuery(hql, expectedType).list();
} catch (QueryTypeMismatchException e) {
    // dynamic HQL: fall back to untyped query with manual mapping
    return mapManually(session.createSelectionQuery(hql).list());
}

Prevention

When it happens

Trigger: createQuery("select count(u) from User u", Integer.class) when count() produces Long; a projection (select new Dto(...)/multi-column) queried with the entity class; expecting a scalar when the select list yields Object[]; DTO constructor signature not matching columns.

Common situations: count queries typed as Integer/int from pre-JPA ports or naive refactors; switching between entity and DTO selects without updating the class argument; multi-select expected as scalar; Java primitives boxed to the wrong wrapper type.

Related errors


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