{"record":{"id":"a74032b61ba34bc4","repo":"hibernate/hibernate-orm","slug":"couldn-t-create-a-java-sql-array","errorCode":null,"errorMessage":"Couldn't create a java.sql.Array","messagePattern":"Couldn't create a java\\.sql\\.Array","errorType":"exception","errorClass":"HibernateException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/dialect/type/OracleArrayJdbcType.java","lineNumber":132,"sourceCode":"\t\t\t}\n\t\t\tcatch (SQLException ex) {\n\t\t\t\tthrow new HibernateException( \"JDBC driver does not support named parameters for setArray. Use positional.\", ex );\n\t\t\t}\n\t\t}\n\n\t\t@Override\n\t\tpublic java.sql.Array getBindValue(X value, WrapperOptions options) throws SQLException {\n\t\t\tfinal var elementBinder = getElementJdbcType().getBinder( pluralJavaType.getElementJavaType() );\n\t\t\tfinal var objects = convertToArray( this, elementBinder, pluralJavaType, value, options );\n\t\t\tfinal String arrayTypeName = typeName( options );\n\t\t\tfinal var oracleConnection =\n\t\t\t\t\toptions.getSession().getJdbcCoordinator().getLogicalConnection().getPhysicalConnection()\n\t\t\t\t\t\t\t.unwrap( OracleConnection.class );\n\t\t\ttry {\n\t\t\t\treturn oracleConnection.createOracleArray( arrayTypeName, objects );\n\t\t\t}\n\t\t\tcatch (Exception e) {\n\t\t\t\tthrow new HibernateException( \"Couldn't create a java.sql.Array\", e );\n\t\t\t}\n\t\t}\n\t}\n\n\t@Override\n\tpublic <X> ValueExtractor<X> getExtractor(final JavaType<X> javaTypeDescriptor) {\n\t\treturn new BasicExtractor<>( javaTypeDescriptor, this ) {\n\t\t\t@Override\n\t\t\tprotected X doExtract(ResultSet rs, int paramIndex, WrapperOptions options) throws SQLException {\n\t\t\t\treturn getArray( this, rs.getArray( paramIndex ), options );\n\t\t\t}\n\n\t\t\t@Override\n\t\t\tprotected X doExtract(CallableStatement statement, int index, WrapperOptions options) throws SQLException {\n\t\t\t\treturn getArray( this, statement.getArray( index ), options );\n\t\t\t}\n\n\t\t\t@Override","sourceCodeStart":114,"sourceCodeEnd":150,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/dialect/type/OracleArrayJdbcType.java#L114-L150","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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)."],"exampleFix":"-- before: mapping references a type that was never created\n@JdbcTypeCode(SqlTypes.ARRAY)\n@Array(length = 50)\nprivate String[] tags;  -- expects SQL type \"TAGS_VARRAY\" that does not exist\n-- after: create the type in the schema\nCREATE OR REPLACE TYPE TAGS_VARRAY AS VARRAY(50) OF VARCHAR2(100);","handlingStrategy":"validation","validationCode":"// Fail fast at startup if the mapped Oracle collection type is missing\ntry (Connection c = dataSource.getConnection();\n     PreparedStatement ps = c.prepareStatement(\n         \"SELECT count(*) FROM all_types WHERE type_name = ?\"); ) {\n    ps.setString(1, \"TAGS_VARRAY\"); // exactly the name used in your mapping (usually UPPERCASE)\n    try (ResultSet rs = ps.executeQuery()) {\n        rs.next();\n        if (rs.getInt(1) == 0) throw new IllegalStateException(\"Oracle array type TAGS_VARRAY not visible to this user\");\n    }\n}","typeGuard":null,"tryCatchPattern":"catch (HibernateException e) {\n    if (\"Couldn't create a java.sql.Array\".equals(e.getMessage())) {\n        throw new MappingConfigurationException(\n            \"Array type missing or inaccessible - check all_types/EXECUTE grant\", e.getCause());\n    }\n    throw e;\n}","preventionTips":["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."],"tags":["oracle","array","sql-array","type-mapping","ddl","schema"],"backgroundTag":"oracle-array-type-missing","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}