hibernate/hibernate-orm · error · HibernateException

JDBC driver does not support named parameters for setArray.

Error message

JDBC driver does not support named parameters for setArray. Use positional.

What it means

Binding an Oracle array (VARRAY / nested table) mapped with OracleArrayJdbcType to a stored-procedure call by parameter NAME: Hibernate falls back to CallableStatement.setObject(name, array, Types.ARRAY), and when the Oracle driver rejects named binding for array values the SQLException is wrapped in this HibernateException. It is a driver capability gap, not a data problem - the identical bind succeeds positionally via PreparedStatement.setArray.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/dialect/type/OracleArrayJdbcType.java:116

		@Override
		protected void doBindNull(CallableStatement st, String name, WrapperOptions options) throws SQLException {
			st.setNull( name, ARRAY, typeName( options ) );
		}

		@Override
		protected void doBind(PreparedStatement st, X value, int index, WrapperOptions options) throws SQLException {
			st.setArray( index, getBindValue( value, options ) );
		}

		@Override
		protected void doBind(CallableStatement st, X value, String name, WrapperOptions options)
				throws SQLException {
			final java.sql.Array arr = getBindValue( value, options );
			try {
				st.setObject( name, arr, ARRAY );
			}
			catch (SQLException ex) {
				throw new HibernateException( "JDBC driver does not support named parameters for setArray. Use positional.", ex );
			}
		}

		@Override
		public java.sql.Array getBindValue(X value, WrapperOptions options) throws SQLException {
			final var elementBinder = getElementJdbcType().getBinder( pluralJavaType.getElementJavaType() );
			final var objects = convertToArray( this, elementBinder, pluralJavaType, value, options );
			final String arrayTypeName = typeName( options );
			final var oracleConnection =
					options.getSession().getJdbcCoordinator().getLogicalConnection().getPhysicalConnection()
							.unwrap( OracleConnection.class );
			try {
				return oracleConnection.createOracleArray( arrayTypeName, objects );
			}
			catch (Exception e) {
				throw new HibernateException( "Couldn't create a java.sql.Array", e );
			}
		}

View on GitHub (pinned to fad1729dce)

Solutions

  1. Switch the procedure call to positional parameter binding (registerParameter(1, ...) / positional ?): setArray-based positional binding is the supported path.
  2. Upgrade the Oracle JDBC driver (ojdbc11/ojdbc8 recent versions) and retest - named-bind support varies by driver release.
  3. If positional is impossible, bypass JPA binding with session.doReturningWork and call oracleConnection.createOracleArray yourself with a positional ?.
  4. Change the PL/SQL signature to accept a delimited string or use a global temporary table instead of a collection parameter.

Example fix

// before - named parameter, fails on Oracle
StoredProcedureQuery q = em.createStoredProcedureQuery("MY_PKG.TAKE_IDS");
q.registerStoredProcedureParameter("p_ids", Object[].class, ParameterMode.IN);
q.setParameter("p_ids", ids);
// after - positional parameter, uses setArray
StoredProcedureQuery q = em.createStoredProcedureQuery("MY_PKG.TAKE_IDS");
q.registerStoredProcedureParameter(1, Object[].class, ParameterMode.IN);
q.setParameter(1, ids);
Defensive patterns

Strategy: fallback

Validate before calling

// Prefer positional binding whenever the procedure takes non-scalar Oracle types
int parameters = 1; // use registerStoredProcedureParameter(1, ...) instead of named registration

Try / catch

try {
    query.setParameter("p_arr", list);            // named bind
} catch (HibernateException e) {
    if (e.getMessage() != null && e.getMessage().contains("named parameters for setArray")) {
        query.setParameter(1, list);              // fall back to positional bind
    } else throw e;
}

Prevention

When it happens

Trigger: Calling a stored procedure through StoredProcedureQuery, @ProcedureCall, or createStoredProcedureQuery where an IN parameter is an Oracle collection type (VARRAY/nested table) mapped with OracleArrayJdbcType, and the parameter is bound by name (setParameter("p_ids", list) on a named-parameter registration). The driver throws on setObject(name, ...), which Hibernate wraps.

Common situations: Migrating Hibernate 5 StoredProcedureCall code to Hibernate 6 mappings that route through OracleArrayJdbcType; legacy PL/SQL APIs that accept VARRAY inputs; older ojdbc versions with narrower named-parameter support.

Related errors


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