hibernate/hibernate-orm · error · ParameterMisuseException

IN parameter not valid for output extraction

Error message

IN parameter not valid for output extraction

What it means

OutputsImpl.getOutputParameterValue(ProcedureParameter) reads values the database wrote back after execution. Before extraction it checks parameter.getMode(); an IN-only parameter is never populated by the database, so there is no output value to read and Hibernate fails fast with ParameterMisuseException instead of returning garbage.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/procedure/internal/OutputsImpl.java:120

			try {
				updateCount = jdbcStatement.getUpdateCount();
			}
			catch (SQLException e) {
				throw convert( e, "Error calling CallableStatement.getUpdateCount" );
			}
		}

		return buildCurrentReturnState( isResultSet, updateCount );
	}

	protected CurrentReturnState buildCurrentReturnState(boolean isResultSet, int updateCount) {
		return new CurrentReturnState( this, isResultSet, updateCount );
	}

	@Override
	public <T> T getOutputParameterValue(ProcedureParameter<T> parameter) {
		if ( parameter.getMode() == ParameterMode.IN ) {
			throw new ParameterMisuseException( "IN parameter not valid for output extraction" );
		}
		final var registration = parameterRegistrations.get( parameter );
		if ( registration == null ) {
			throw new IllegalArgumentException( "Parameter [" + parameter + "] is not registered with this procedure call" );
		}
		try {
			if ( registration.getParameterMode() == ParameterMode.REF_CURSOR ) {
				//noinspection unchecked
				return (T) registration.getRefCursorExtractor().extractResultSet(
						jdbcStatement,
						procedureCall.getSession()
				);
			}
			else {
				//noinspection unchecked
				return (T) registration.getParameterExtractor().extractValue(
						jdbcStatement,
						parameter.getPosition() == null,

View on GitHub (pinned to fad1729dce)

Solutions

  1. Register the parameter as INOUT (registerStoredProcedureParameter(1, Integer.class, ParameterMode.INOUT)) so the database returns the final value.
  2. Only call getOutputParameterValue for parameters whose getMode() is OUT, INOUT or REF_CURSOR.
  3. If you only need the value you bound, use your own variable instead of extracting it.

Example fix

// before
proc.registerStoredProcedureParameter(1, Integer.class, ParameterMode.IN);
proc.setParameter(1, 42);
proc.execute();
int n = (Integer) proc.getOutputParameterValue(1); // throws

// after
proc.registerStoredProcedureParameter(1, Integer.class, ParameterMode.INOUT);
proc.setParameter(1, 42);
proc.execute();
int n = (Integer) proc.getOutputParameterValue(1);
Defensive patterns

Strategy: validation

Validate before calling

// only extract parameters the database actually writes back
StoredProcedureParameter<?> target = proc.getParameters().stream()
        .filter( p -> Objects.equals( p.getPosition(), position ) )
        .findFirst().orElse( null );
if ( target == null || target.getMode() == ParameterMode.IN ) {
    throw new IllegalArgumentException( "position " + position + " is not an output parameter" );
}
Object value = proc.getOutputParameterValue( position );

Type guard

static boolean isExtractable(StoredProcedureParameter<?> p) {
    return p.getMode() == ParameterMode.OUT
            || p.getMode() == ParameterMode.INOUT
            || p.getMode() == ParameterMode.REF_CURSOR;
}

Try / catch

try {
    Object v = proc.getOutputParameterValue( param );
} catch (ParameterMisuseException e) {
    // the parameter is IN-only; nothing to read back
}

Prevention

When it happens

Trigger: storedProcedureQuery.getOutputParameterValue(param) where param was registered with ParameterMode.IN; the position/name overloads (getOutputParameterValue(1)) when that position is an IN parameter.

Common situations: Forgetting to declare INOUT/OUT on registration; positional miscounting after a function-return parameter shift; porting from drivers that tolerated reading IN values; reading back a value you only intended to bind.

Related errors


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