hibernate/hibernate-orm · error · IllegalArgumentException

Cannot specify both result-set mapping names and classes

Error message

Cannot specify both result-set mapping names and classes

What it means

Util.resolveResultSetMappings(String[],String[],...) refuses ambiguity: if both resultSetMappingNames and resultSetMappingClasses arrays are non-empty it throws IllegalArgumentException, because Hibernate cannot apply two mapping strategies to one call. These arrays come from the resultClasses / resultSetMappings attributes of @NamedStoredProcedureQuery (ProcedureCallHints) or from how the call was created.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/procedure/internal/Util.java:37

 * Utilities used to implement procedure call support.
 *
 * @author Steve Ebersole
 */
public class Util {

	private Util() {
	}

	public static List<ResultSetMapping> resolveResultSetMappings(
			String procedureName,
			String[] resultSetMappingNames,
			Class<?>[] resultSetMappingClasses,
			Consumer<String> querySpaceConsumer,
			ResultSetMappingResolutionContext context) {
		if ( !isEmpty( resultSetMappingNames ) ) {
			// cannot specify both
			if ( !isEmpty( resultSetMappingClasses ) ) {
				throw new IllegalArgumentException( "Cannot specify both result-set mapping names and classes" );
			}
			return resolveResultSetMappings( procedureName, resultSetMappingNames, querySpaceConsumer, context );
		}
		else if ( !isEmpty( resultSetMappingClasses ) ) {
			return resolveResultSetMappings( procedureName, resultSetMappingClasses, querySpaceConsumer, context );
		}
		else {
			return List.of( resolveResultSetMapping( procedureName, true, context.getSessionFactory() ) );
		}
	}

	public static void resolveResultSetMappings(
			String[] resultSetMappingNames,
			Class<?>[] resultSetMappingClasses,
			ResultSetMapping resultSetMapping,
			Consumer<String> querySpaceConsumer,
			ResultSetMappingResolutionContext context) {
		if ( !isEmpty( resultSetMappingNames ) ) {

View on GitHub (pinned to fad1729dce)

Solutions

  1. Keep exactly one of resultClasses or resultSetMappings on the annotation / hints
  2. If a mix of entity and scalar results is needed, encode both inside a single @SqlResultSetMapping (@EntityResult plus @ColumnResult) and reference it by name
  3. Add a bootstrap test that instantiates every @NamedStoredProcedureQuery to catch this at build time

Example fix

// before
@NamedStoredProcedureQuery(name = "loadOrder",
    procedureName = "load_order",
    resultClasses = { Order.class },
    resultSetMappings = { "orderMapping" })

// after
@NamedStoredProcedureQuery(name = "loadOrder",
    procedureName = "load_order",
    resultSetMappings = { "orderMapping" })
Defensive patterns

Strategy: validation

Validate before calling

if (resultSetMappingNames.length > 0 && resultSetMappingClasses.length > 0) {
    throw new IllegalStateException("Configure either resultClasses or resultSetMappings, not both");
}

Try / catch

try {
    ProcedureCall call = session.createNamedStoredProcedureCall("loadOrder");
} catch (IllegalArgumentException e) {
    // both mapping styles configured on the named call: remove one attribute
}

Prevention

When it happens

Trigger: @NamedStoredProcedureQuery(name = "loadOrder", procedureName = "load_order", resultClasses = { Order.class }, resultSetMappings = { "orderMapping" }) — both attributes populated; or building ProcedureCallHints with both arrays set.

Common situations: Copy-pasting annotation fragments from two different examples; adding resultSetMappings and forgetting to remove resultClasses; refactoring from class-based mappings to named mappings without cleaning the annotation.

Related errors


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