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

Thrown as QueryTypeMismatchException (a HibernateException) by SqmUtil.throwQueryTypeMismatchException when the type produced by the query's select item is not assignable to the result class you gave when creating the query. Before executing, Hibernate compares the SQM expression's SqmExpressible type name against the expected Java class; a mismatch (query produces String, you asked for Person) fails fast instead of producing a ClassCastException later.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmUtil.java:1376

	private static boolean isMatchingDateJdbcType(Class<?> resultClass, JdbcType jdbcType) {
		if ( jdbcType != null ) {
			return switch ( jdbcType.getDefaultSqlTypeCode() ) {
				case Types.DATE -> resultClass.isAssignableFrom(java.sql.Date.class);
				case Types.TIME -> resultClass.isAssignableFrom(java.sql.Time.class);
				case Types.TIMESTAMP -> resultClass.isAssignableFrom(java.sql.Timestamp.class);
				default -> false;
			};
		}
		else {
			return false;
		}
	}

	private static void throwQueryTypeMismatchException(
			Class<?> resultClass,
			@Nullable SqmExpressible<?> sqmExpressible, @Nullable Class<?> javaTypeClass) {
		throw new QueryTypeMismatchException( String.format(
				Locale.ROOT,
				"Incorrect query result type: query produces '%s' but type '%s' was given",
				sqmExpressible == null ? javaTypeClass.getName() : sqmExpressible.getTypeName(),
				resultClass.getName()
		) );
	}

	public static Set<ParameterExpression<?>> getParameters(SqmStatement<?> statement) {
		final var parameters = statement.getSqmParameters();
		return switch ( parameters.size() ) {
			case 0 -> emptySet();
			case 1 -> {
				final var parameter = parameters.iterator().next();
				yield parameter instanceof ValueBindJpaCriteriaParameter
						? emptySet()
						: singleton( parameter );
			}
			default -> {

View on GitHub (pinned to fad1729dce)

Solutions

  1. Make the result class match what the select produces: createQuery(hql, String.class) for 'select p.name'
  2. Change the select to produce the expected type: 'select p from Person p' for Person.class
  3. For multiple/scalar items use Object[] or a Tuple/construct(...) DTO result type
  4. For numeric IDs use the exact Java type of the id attribute (usually Long)

Example fix

// before
Query<Person> q = session.createQuery("select p.name from Person p", Person.class);
// after
Query<String> q = session.createQuery("select p.name from Person p", String.class);
Defensive patterns

Strategy: try-catch

Validate before calling

null // the produced type is only known after SQM analysis; keep the result class and select expression in one place instead

Type guard

static boolean resultTypeMatches(Class<?> produced, Class<?> expected) {
    return produced != null && produced.isAssignableFrom(expected) || expected.isAssignableFrom(produced);
}

Try / catch

try {
    return session.createQuery(hql, resultClass).getResultList();
} catch (QueryTypeMismatchException e) {
    throw new IllegalArgumentException(
        "Result class " + resultClass.getName() + " does not match select item of: " + hql, e);
}

Prevention

When it happens

Trigger: session.createQuery("select p.name from Person p", Person.class); selecting p.id (Long) but passing Integer.class; criteria .select(cb.count(root)) with a result class other than Long; array/compound selections where the component type does not match the expected array component class.

Common situations: Refactoring a query from entity select to scalar/DTO projection without updating the result class; generic DAO APIs where the caller-supplied result class drifts from the actual select; numeric type mismatches after changing an @Id generation type; tuple queries declared with the entity class.

Related errors


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