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 );
}
@OverrideView on GitHub (pinned to fad1729dce)
Solutions
- 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).
- Grant EXECUTE on the collection type to the application database user.
- Ensure the DDL step of your migration creates the collection type before the application binds arrays.
- 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
- Create Oracle collection types (CREATE TYPE ... AS VARRAY/TABLE OF) in the same migration that adds the columns using them.
- Always spell mapped type names UPPERCASE and schema-qualify when they live in another schema.
- Grant EXECUTE on collection types to the application user in your baseline DDL.
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
- SingleStore does not support dropping creating/dropping sche
- JDBC driver does not support named parameters for setArray.
- Unable to determine SQL type name for column '%s' of table '
- Cannot parse given string into array of Shorts. First and la
- No type mapping for org.hibernate.type.SqlTypes code: %s (%s
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/a74032b61ba34bc4.
Report an issue: GitHub.