hibernate/hibernate-orm · error · UnsupportedOperationException

ProcedureCall cannot be treated as a selection query

Error message

ProcedureCall cannot be treated as a selection query

What it means

When a named query is resolved with selection semantics (session.createNamedSelectionQuery(name, type), see AbstractSharedSessionContract), Hibernate asks the stored memento to convert itself via toSelectionQuery(session). NamedCallableQueryMementoImpl, the memento for @NamedStoredProcedureQuery registrations, cannot become a SelectionQueryImplementor because stored-procedure results are consumed through ProcedureCall.getOutputs(), so it throws UnsupportedOperationException.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/procedure/internal/NamedCallableQueryMementoImpl.java:170

		return makeProcedureCall( session );
	}

	@Nonnull
	@Override
	public MutationQueryImplementor<Object> toMutationQuery(@Nonnull SharedSessionContractImplementor session) {
		throw new UnsupportedOperationException( "ProcedureCall cannot be treated as a mutation query" );
	}

	@Nonnull
	@Override
	public <T> MutationQueryImplementor<T> toMutationQuery(@Nonnull SharedSessionContractImplementor session, @Nullable Class<T> targetType) {
		throw new UnsupportedOperationException( "ProcedureCall cannot be treated as a mutation query" );
	}

	@Nonnull
	@Override
	public SelectionQueryImplementor<Object> toSelectionQuery(@Nonnull SharedSessionContractImplementor session) {
		throw new UnsupportedOperationException( "ProcedureCall cannot be treated as a selection query" );
	}

	@Nonnull
	@Override
	public <T> SelectionQueryImplementor<T> toSelectionQuery(@Nonnull SharedSessionContractImplementor session, @Nullable Class<T> javaType) {
		throw new UnsupportedOperationException( "ProcedureCall cannot be treated as a selection query" );
	}

	@Nonnull
	@Override
	public NamedQueryMemento<Object> makeCopy(@Nonnull String name) {
		return new NamedCallableQueryMementoImpl( name, this );
	}

	@Override
	public void validate(@Nonnull QueryEngine queryEngine) {
		// anything to do?
	}

View on GitHub (pinned to fad1729dce)

Solutions

  1. Create the procedure query via em.createNamedStoredProcedureQuery(name) or session.getNamedProcedureCall(name) and consume results with getResultList()/getOutputs().
  2. Use em.createNamedQuery(name, SomeClass.class), which routes the callable memento to makeProcedureCall instead of toSelectionQuery.
  3. If the procedure only returns data, consider a native selection query over a table function (select * from f(...)) instead.

Example fix

// before
SelectionQuery<AuditRow> q = session.createNamedSelectionQuery("audit_rows_proc", AuditRow.class);

// after
ProcedureCall call = session.getNamedProcedureCall("audit_rows_proc");
List<AuditRow> rows = call.getResultList();
Defensive patterns

Strategy: validation

Validate before calling

final NamedQueryMemento<?> memento = ((SessionFactoryImplementor) sessionFactory)
        .getQueryEngine().getNamedObjectRepository()
        .getQueryMementoByName( queryName, false );
if ( memento instanceof NamedCallableQueryMemento ) {
    ProcedureCall<?> call = session.getNamedProcedureCall( queryName ); // selection path
    List<?> results = call.getResultList();
} else {
    SelectionQuery<?> q = session.createNamedSelectionQuery( queryName, type );
}

Type guard

static boolean isCallableNamedQuery(String name, SessionFactoryImplementor sf) {
    return sf.getQueryEngine().getNamedObjectRepository()
            .getQueryMementoByName( name, false )
            instanceof NamedCallableQueryMemento;
}

Try / catch

try {
    SelectionQuery<R> q = session.createNamedSelectionQuery( name, type );
} catch (UnsupportedOperationException e) {
    List<R> rows = (List<R>) session.getNamedProcedureCall( name ).getResultList();
}

Prevention

When it happens

Trigger: Calling session.createNamedSelectionQuery("procName", SomeClass.class) where procName is a @NamedStoredProcedureQuery; any code that resolves named queries strictly through the SelectionQuery contract.

Common situations: Post-6.5 migrations that replaced createNamedQuery casts with createSelectionQuery; read-only service layers that normalize every named query to SelectionQuery; test fixtures that iterate all named queries through one creation API.

Related errors


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