hibernate/hibernate-orm · error · HibernateException

Illegal null value for array index encountered while reading

Error message

Illegal null value for array index encountered while reading: 

What it means

For array-mapped collections (primitive/object arrays), each row's position is assembled from the index column (adjusted for indexBase). ArrayInitializer.readCollectionRow throws HibernateException 'Illegal null value for array index encountered while reading' plus the collection's navigable role when that index value assembles to null - arrays cannot hold a null index, so the row is unusable. Null elements are tolerated (NotFound handling); null indexes are not.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/sql/results/graph/collection/internal/ArrayInitializer.java:86

	protected void forEachSubInitializer(BiConsumer<Initializer<?>, RowProcessingState> consumer, InitializerData data) {
		super.forEachSubInitializer( consumer, data );
		final var initializer = elementAssembler.getInitializer();
		if ( initializer != null ) {
			consumer.accept( initializer, data.getRowProcessingState() );
		}
	}

	@Override
	public @Nullable PersistentArrayHolder<?> getCollectionInstance(ImmediateCollectionInitializerData data) {
		return (PersistentArrayHolder<?>) super.getCollectionInstance( data );
	}

	@Override
	protected void readCollectionRow(ImmediateCollectionInitializerData data, List<Object> loadingState) {
		final var rowProcessingState = data.getRowProcessingState();
		final Integer indexValue = listIndexAssembler.assemble( rowProcessingState );
		if ( indexValue == null ) {
			throw new HibernateException( "Illegal null value for array index encountered while reading: "
					+ getCollectionAttributeMapping().getNavigableRole() );
		}
		final Object element = elementAssembler.assemble( rowProcessingState );
		if ( element == null ) {
			// If element is null, then NotFoundAction must be IGNORE
			return;
		}
		int index = indexValue;

		if ( indexBase != 0 ) {
			index -= indexBase;
		}

		for ( int i = loadingState.size(); i <= index; ++i ) {
			loadingState.add( i, null );
		}

		loadingState.set( index, element );

View on GitHub (pinned to fad1729dce)

Solutions

  1. Fix the data: populate non-null, contiguous index values for the affected collection rows
  2. Add a NOT NULL constraint on the index column so bad rows cannot re-enter
  3. Verify the @OrderColumn/@IndexColumn mapping names the real index column and that indexBase matches how data was written
  4. Backfill outside Hibernate if the table was populated by other tooling: UPDATE t SET idx = <row_number per owner> WHERE idx IS NULL

Example fix

// mapping under scrutiny
@OneToMany
@OrderColumn( name = "idx", nullable = false )
private LineItem[] items;

-- repair data so the index is never null
UPDATE OrderLines SET idx = (SELECT COUNT(*) FROM OrderLines o2
  WHERE o2.order_id = OrderLines.order_id AND o2.id < OrderLines.id)
WHERE idx IS NULL;
Defensive patterns

Strategy: validation

Validate before calling

-- run before relying on an array-mapped collection: no null indexes allowed
SELECT owner_id FROM join_table WHERE index_column IS NULL;
-- any rows returned must be repaired first

Prevention

When it happens

Trigger: Reading an array-mapped collection whose index column (@OrderColumn/@IndexColumn, or the idx column of the join table) contains NULL in some rows; mapping mistakes where the configured index column is nullable or is the wrong column entirely.

Common situations: Manually inserted or ETL-loaded join-table rows without index values; join tables written by legacy code leaving idx null; @OrderColumn naming the wrong column; data migrated from a system that had no array ordering.

Related errors


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