hibernate/hibernate-orm · error · MappingException

NamedStoredProcedureQuery [%s] specified both resultClasses

Error message

NamedStoredProcedureQuery [%s] specified both resultClasses and resultSetMappings

What it means

JPA lets @NamedStoredProcedureQuery describe its results either with resultClasses or with resultSetMappings, never both. NamedProcedureCallDefinitionImpl's constructor checks both annotation attributes during bootstrap and throws this MappingException (naming the query's registered name) when both arrays are non-empty, because Hibernate cannot decide which result shape applies.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/boot/query/internal/NamedProcedureCallDefinitionImpl.java:66

	private final String[] resultSetMappings;
	private final ParameterDefinitions parameterDefinitions;
	private final Map<String, Object> hints;

	public NamedProcedureCallDefinitionImpl(@Nonnull NamedStoredProcedureQuery annotation) {
		registeredName = annotation.name();
		procedureName = annotation.procedureName();
		hints = new QueryHintDefinition( registeredName, annotation.hints() ).getHintsMap();

		resultClasses = annotation.resultClasses();
		resultSetMappings = annotation.resultSetMappings();

		parameterDefinitions = new ParameterDefinitions( annotation.parameters() );

		final boolean specifiesResultClasses = resultClasses != null && resultClasses.length > 0;
		final boolean specifiesResultSetMappings = resultSetMappings != null && resultSetMappings.length > 0;

		if ( specifiesResultClasses && specifiesResultSetMappings ) {
			throw new MappingException(
					String.format(
							"NamedStoredProcedureQuery [%s] specified both resultClasses and resultSetMappings",
							registeredName
					)
			);
		}
	}

	@Nonnull
	@Override
	public String getRegistrationName() {
		return registeredName;
	}

	@Nonnull
	@Override
	public QueryFlushMode getQueryFlushMode() {
		return QueryFlushMode.DEFAULT;

View on GitHub (pinned to fad1729dce)

Solutions

  1. Keep exactly one of the two attributes: delete resultClasses if you want SqlResultSetMapping-based results, or delete resultSetMappings if you want entity-class results
  2. If you need both shapes, define two separate @NamedStoredProcedureQuery entries with different names
  3. Rebuild/redeploy so the corrected annotation is reprocessed

Example fix

// before
@NamedStoredProcedureQuery(
  name = "countOrders",
  procedureName = "count_orders",
  resultClasses = { OrderCount.class },
  resultSetMappings = { "OrderCountMapping" }) // both set -> MappingException

// after
@NamedStoredProcedureQuery(
  name = "countOrders",
  procedureName = "count_orders",
  resultSetMappings = { "OrderCountMapping" })
Defensive patterns

Strategy: validation

Validate before calling

// Deployment-time check over annotated classes
for (AnnotatedElement el : annotatedElements) {
    NamedStoredProcedureQuery q = el.getAnnotation(NamedStoredProcedureQuery.class);
    if (q != null && q.resultClasses().length > 0 && q.resultSetMappings().length > 0) {
        throw new IllegalStateException("@NamedStoredProcedureQuery " + q.name()
            + " must not set both resultClasses and resultSetMappings");
    }
}

Try / catch

try {
    sessionFactory = metadata.buildSessionFactory();
} catch (MappingException e) {
    if (e.getMessage().contains("resultClasses and resultSetMappings")) {
        // identify the named query from the message and remove one attribute
    }
    throw e;
}

Prevention

When it happens

Trigger: An @NamedStoredProcedureQuery annotation that sets both resultClasses = {X.class} and resultSetMappings = {"..."}; both arrays non-empty triggers the MappingException while Hibernate processes annotated entities during EntityManagerFactory/SessionFactory build.

Common situations: Adding resultSetMappings to an existing annotation and forgetting to remove resultClasses; copy-paste from another named query; migrations between the two result strategies; IDE auto-completion filling in both attributes.

Related errors


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