hibernate/hibernate-orm · error · IllegalArgumentException

Result class is null

Error message

Result class is null

What it means

createNamedQuery(name, resultClass) declares the result class @Nonnull and fails fast with IllegalArgumentException('Result class is null') before any name lookup. The typed overload cannot mean 'any type', so callers must either pass a concrete Class or use the single-argument createNamedQuery(name).

Source

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










	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Named Query
	@Override
	@Nonnull
	public <R> SelectionQueryImplementor<R> createNamedQuery(@Nonnull String name, @Nonnull Class<R> resultClass) {
		checksBeforeQueryCreation();
		//noinspection ConstantValue
		if ( resultClass == null ) {
			throw new IllegalArgumentException( "Result class is null" );
		}
		try {
			final QueryImplementor<R> query = buildNamedQuery( name,
					memento -> createSqmQueryImplementor( resultClass, memento ),
					memento -> createNativeQueryImplementor( resultClass, memento ) );
			if ( query instanceof SelectionQueryImplementor<R> selectionQuery ) {
				return selectionQuery;
			}
			else {
				// JPA implies (though is not very explicit) that this should lead
				// to an IllegalArgumentException.  Yuck, but...
				var msg = "Named query is not a selection query : " + name;
				var iae = new IllegalArgumentException( msg );
				iae.addSuppressed( new IllegalSelectQueryException( msg, query.getQueryString() ) );
				throw iae;
			}
		}
		catch (RuntimeException e) {

View on GitHub (pinned to fad1729dce)

Solutions

  1. Use the untyped createNamedQuery(name) when no concrete result class applies.
  2. Fix the generic plumbing so a real Class<T> reaches the call; requireNonNull with a descriptive message near the source.
  3. Validate optional type parameters at construction time of the helper rather than at query creation.

Example fix

// before
public <T> List<T> byName(String name, Class<T> type) {
    return em.createNamedQuery(name, type).getResultList(); // type null -> throws
}
// after
public <T> List<T> byName(String name, Class<T> type) {
    return type != null ? em.createNamedQuery(name, type).getResultList()
                        : em.createNamedQuery(name).getResultList();
}
Defensive patterns

Strategy: type-guard

Type guard

static <T> Class<T> requireResultClass(@Nullable Class<T> type) {
    return Objects.requireNonNull(type, "resultClass must not be null; use createNamedQuery(name)");
}

// usage
return em.createNamedQuery(name, requireResultClass(type)).getResultList();

Prevention

When it happens

Trigger: Passing null explicitly, or a generic Class<T> variable that is null at runtime: unchecked casts of never-set fields, Optional.orElse(null), Map.get(key) with a missing key, or nullable Kotlin values crossing into Java.

Common situations: Generic repository helpers plumbing an optional type parameter that some callers never set; refactors that removed the class argument but kept the two-arg overload; DI/config-supplied Class fields left null by a misconfigured bean.

Related errors


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