hibernate/hibernate-orm · error · HibernateException

Couldn't create a java.sql.Array

Error message

Couldn't create a java.sql.Array

What it means

To bind an array value, OracleArrayJdbcType.getBindValue unwraps the physical connection to oracle.jdbc.OracleConnection and calls createOracleArray(arrayTypeName, elements). Any failure - most often the named collection type not existing in the schema or not being visible to the DB user, wrong casing, missing EXECUTE privilege, or a driver/connection incompatibility - is caught by 'catch (Exception e)' and wrapped. The nested cause holds the real error; the type name used comes from your mapping.

Source

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

			}
			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 );
			}
		}
	}

	@Override
	public <X> ValueExtractor<X> getExtractor(final JavaType<X> javaTypeDescriptor) {
		return new BasicExtractor<>( javaTypeDescriptor, this ) {
			@Override
			protected X doExtract(ResultSet rs, int paramIndex, WrapperOptions options) throws SQLException {
				return getArray( this, rs.getArray( paramIndex ), options );
			}

			@Override
			protected X doExtract(CallableStatement statement, int index, WrapperOptions options) throws SQLException {
				return getArray( this, statement.getArray( index ), options );
			}

			@Override

View on GitHub (pinned to fad1729dce)

Solutions

  1. Verify the type exists and matches exactly: SELECT type_name FROM all_types WHERE type_name = 'YOUR_TYPE'; create it or fix the mapped name (usually UPPERCASE, schema-qualified if needed).
  2. Grant EXECUTE on the collection type to the application database user.
  3. Ensure the DDL step of your migration creates the collection type before the application binds arrays.
  4. Upgrade the Oracle JDBC driver so createOracleArray works with your DB version and connection pool (pools must unwrap cleanly to OracleConnection).

Example fix

-- before: mapping references a type that was never created
@JdbcTypeCode(SqlTypes.ARRAY)
@Array(length = 50)
private String[] tags;  -- expects SQL type "TAGS_VARRAY" that does not exist
-- after: create the type in the schema
CREATE OR REPLACE TYPE TAGS_VARRAY AS VARRAY(50) OF VARCHAR2(100);
Defensive patterns

Strategy: validation

Validate before calling

// Fail fast at startup if the mapped Oracle collection type is missing
try (Connection c = dataSource.getConnection();
     PreparedStatement ps = c.prepareStatement(
         "SELECT count(*) FROM all_types WHERE type_name = ?"); ) {
    ps.setString(1, "TAGS_VARRAY"); // exactly the name used in your mapping (usually UPPERCASE)
    try (ResultSet rs = ps.executeQuery()) {
        rs.next();
        if (rs.getInt(1) == 0) throw new IllegalStateException("Oracle array type TAGS_VARRAY not visible to this user");
    }
}

Try / catch

catch (HibernateException e) {
    if ("Couldn't create a java.sql.Array".equals(e.getMessage())) {
        throw new MappingConfigurationException(
            "Array type missing or inaccessible - check all_types/EXECUTE grant", e.getCause());
    }
    throw e;
}

Prevention

When it happens

Trigger: INSERT/UPDATE/flush of an entity attribute mapped as an Oracle array (OracleArrayJdbcType with a type name, e.g. @JdbcTypeCode(SqlTypes.ARRAY)) when that name does not match an existing CREATE TYPE ... AS VARRAY/TABLE OF, lives in another schema without a synonym or privilege, was dropped/recreated, or the connection unwrap/driver combination fails createOracleArray.

Common situations: Running against a fresh schema where the DDL for the collection type was never generated; case mismatch between the Java mapping ('myArrayType') and Oracle's default uppercase type names; missing EXECUTE grant for the application user; old ojdbc jar against a newer database.

Related errors


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