hibernate/hibernate-orm · error · IllegalStateException

array case should be treated at upper level

Error message

array case should be treated at upper level

What it means

OsonDocumentWriter.serializeValue switches on the nested value's JDBC type code to render a JSON leaf. ARRAY and JSON_ARRAY are deliberately rejected with IllegalStateException 'array case should be treated at upper level': arrays must be written by JsonGeneratingVisitor.visitArray (startArray, per-element visit, endArray), never as a single leaf value. Reaching this branch means an array JdbcType was handed straight to the leaf serializer.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/type/format/OsonDocumentWriter.java:244

				break;

			case SqlTypes.DURATION:
			case SqlTypes.UUID:
				generator.write( javaType.toString( (T)value ) );
				break;
			case SqlTypes.BINARY:
			case SqlTypes.VARBINARY:
			case SqlTypes.LONGVARBINARY:
			case SqlTypes.LONG32VARBINARY:
			case SqlTypes.BLOB:
			case SqlTypes.MATERIALIZED_BLOB:
				// how to handle
				byte[] bytes = javaType.unwrap( (T)value, byte[].class, options );
				generator.write( bytes );
				break;
			case SqlTypes.ARRAY:
			case SqlTypes.JSON_ARRAY:
				throw new IllegalStateException( "array case should be treated at upper level" );
			default:
				throw new UnsupportedOperationException( "Unsupported JdbcType nested in JSON: " + jdbcType );
		}

	}

}

View on GitHub (pinned to fad1729dce)

Solutions

  1. Flatten the structure - store List<ElementType> with a non-array element type, or wrap each nested array inside an embeddable
  2. Map the whole nested structure as a single JSON value (@JdbcTypeCode(SqlTypes.JSON)) instead of per-element array types
  3. Upgrade Hibernate ORM - routing between visitor and writer has received fixes; report with a mapping reproducer if it persists

Example fix

// before
@JdbcTypeCode(SqlTypes.ARRAY)
private int[][] matrix; // element JDBC type is again ARRAY -> 'array case should be treated at upper level'

// after
@JdbcTypeCode(SqlTypes.JSON)
private List<List<Integer>> matrix; // one JSON document, no nested array JDBC types
Defensive patterns

Strategy: validation

Validate before calling

// Startup check: no nested plural-of-plural mappings for JSON aggregates on Oracle
int elementCode = elementJdbcType.getDefaultSqlTypeCode();
if (elementCode == SqlTypes.ARRAY || elementCode == SqlTypes.JSON_ARRAY) {
    throw new IllegalStateException("Nested array JDBC types cannot be serialized to JSON; flatten the mapping");
}

Prevention

When it happens

Trigger: A nested/multi-dimensional plural mapping where an element's own JdbcType still resolves to ARRAY or JSON_ARRAY - e.g. int[][], List<int[]>, or a JSON aggregate whose element is itself array-typed - serialized through the Oracle OSON writer during flush.

Common situations: Modeling matrix/nested-array data in JSON columns on Oracle; mapping changes that alter element-type resolution; version upgrades changing how plural elements are routed between the visitor and the writer.

Related errors


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