hibernate/hibernate-orm · error · UnsupportedOperationException

generic collections don't have indexes

Error message

generic collections don't have indexes

What it means

CollectionType.indexOf (CollectionType.java:69) is the base implementation for collection types that have no positional index; it throws UnsupportedOperationException ('generic collections don't have indexes') because only indexed collections - List mapped with @OrderColumn/@ListIndexBase and Map with a key - can answer 'at which position does this element sit'. Any operation asking for element indexes against a Set/Bag-mapped role fails here.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/type/CollectionType.java:70

	private final String foreignKeyPropertyName;

	// the need for the persister if very hot in many use cases: cache it in a field
	// TODO initialize it at constructor time
	private volatile CollectionPersister persister;

	public CollectionType(String role, String foreignKeyPropertyName) {
		this.role = role;
		this.foreignKeyPropertyName = foreignKeyPropertyName;
	}

	public abstract CollectionClassification getCollectionClassification();

	public String getRole() {
		return role;
	}

	public Object indexOf(Object collection, Object element) {
		throw new UnsupportedOperationException( "generic collections don't have indexes" );
	}

	public boolean contains(Object collection, Object childObject, SharedSessionContractImplementor session) {
		// we do not have to worry about queued additions to uninitialized
		// collections, since they can only occur for inverse collections!
		final var elems = getElementsIterator( collection );
		while ( elems.hasNext() ) {
			final Object maybeProxy = elems.next();
			// worrying about proxies is perhaps a little bit of overkill here...
			final var initializer = extractLazyInitializer( maybeProxy );
			final Object element =
					initializer != null && !initializer.isUninitialized()
							? initializer.getImplementation()
							: maybeProxy;
			if ( element == childObject ) {
				return true;
			}
		}

View on GitHub (pinned to fad1729dce)

Solutions

  1. If order matters, map the collection as a List with @OrderColumn (or a Map with @MapKeyColumn) so indexes exist.
  2. If order does not matter, rewrite the query to use element membership/elements instead of index functions.
  3. Check the persister: for Set-typed roles there is no index by definition - restructure the query or the model.
  4. Replace legacy 'indices(...)'/'index(...)' HQL with @OrderColumn-based list handling or explicit position columns.

Example fix

// before (lines is Set<Line>)
List<Integer> idx = session.createQuery(
    "select index(l) from Order o join o.lines l", Integer.class)
    .getResultList(); // UnsupportedOperationException

// after: map as ordered List
@OneToMany(mappedBy = "order")
@OrderColumn(name = "position")
private List<Line> lines = new ArrayList<>();
// then 'select index(l) ...' is valid
Defensive patterns

Strategy: validation

Validate before calling

// Before querying, verify the collection actually has an index
CollectionPersister p = ((SessionFactoryImplementor) sessionFactory)
        .getMappingMetamodel().getCollectionDescriptor(Order.class.getName() + ".lines");
if (!p.hasIndex()) {
    throw new IllegalStateException(
        "Order.lines is a Set/Bag; index()/indices() queries are not valid");
}

Type guard

static boolean isIndexedCollection(Collection<?> c) {
    return c instanceof List<?> || c instanceof Map<?, ?>;
}

Prevention

When it happens

Trigger: HQL that requests the index of elements on a collection mapped as Set or Bag (e.g. 'select index(d.lines) from Order d' or legacy 'indices(...)' where lines is a Set/@ElementCollection without @OrderColumn); programmatic calls to CollectionType.indexOf(collection, element) on a set/bag role; internal paths that build indexed snapshots for a role whose persister is not indexed.

Common situations: Changing a @OneToMany List to Set (for uniqueness) while old queries still use index()/list()-style expressions; porting legacy Hibernate 3/4 HQL that used indices()/elements(); assuming @ElementCollection of an ordered DB collection is index-addressable without @OrderColumn.

Related errors


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