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
- Make the result class match what the select produces: createQuery(hql, String.class) for 'select p.name'
- Change the select to produce the expected type: 'select p from Person p' for Person.class
- For multiple/scalar items use Object[] or a Tuple/construct(...) DTO result type
- 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
- Derive the result class from the same source as the select expression (constant or metamodel lookup)
- Write one smoke test per named query asserting its result type
- For scalar selects use createQuery(hql, String.class/Long.class), for entities the entity class, for multi-select Object[] or Tuple
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
- Named query definition is null
- Named query definition name is null: %s
- Duplicate named query '%s'
- Named native query definition object is null
- Named native query definition name is null: {}
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/9724842bbd4f6bb0.
Report an issue: GitHub.