hibernate/hibernate-orm · error · UnsupportedOperationException
Bags don't have indexes :
Error message
Bags don't have indexes :
What it means
getIndex is part of the collection SPI used for indexed collections (lists with an order column, maps). A bag has no positional index by definition, so PersistentBag implements getIndex by throwing UnsupportedOperationException with the collection role. The throw means some code path asked this bag's entries for element indexes: usually mapping metadata that implies an index while the runtime collection is a bag, or direct use of the collection SPI.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/collection/spi/PersistentBag.java:532
}
@Override
public void clear() {
if ( isClearQueueEnabled() ) {
queueOperation( new Clear() );
}
else {
initialize( true );
if ( !collection.isEmpty() ) {
collection.clear();
dirty();
}
}
}
@Override
public Object getIndex(Object entry, int i, CollectionPersister persister) {
throw new UnsupportedOperationException( "Bags don't have indexes : " + persister.getRole() );
}
@Override
public Object getElement(Object entry) {
return entry;
}
@Override
public Object getSnapshotElement(Object entry, int i) {
final List<?> sn = (List<?>) getSnapshot();
return sn.get( i );
}
/**
* Count how many times the given object occurs in the elements
*
* @param o The object to check
*View on GitHub (pinned to fad1729dce)
Solutions
- Make the mapping consistent: <list> or @OrderColumn with a List field for indexed collections, plain bag/Collection for unordered
- Ensure the Java field type matches the mapping kind (List for indexed mappings)
- Clean rebuild and purge stale hbm.xml resources or duplicate mapping files
- Do not call PersistentCollection#getIndex yourself; use the collection's public API
Example fix
// before @OneToMany(mappedBy = "order") private Collection<OrderLine> lines; // index-dependent code path against a bag // after @OneToMany(mappedBy = "order") @OrderColumn(name = "line_no") private List<OrderLine> lines;
Defensive patterns
Strategy: validation
Validate before calling
CollectionPersister cp = sessionFactory.getDomainModel()
.findCollectionDescriptor(Order.class.getName() + ".lines");
if (cp == null || !cp.hasIndex()) {
// not an indexed collection; skip index-dependent logic
} Type guard
static boolean hasIndexColumn(Field field) {
return field.isAnnotationPresent(OrderColumn.class)
|| Map.class.isAssignableFrom(field.getType());
} Prevention
- Decide ordering at mapping time: bags are unordered, lists are indexed
- Keep field type and mapping kind in sync
- Do not rely on positional access for bag-mapped collections
When it happens
Trigger: Mapping declared as indexed (<list>, @OrderColumn/@ListIndexBase) while the runtime wrapper or persister resolves the collection as a bag; programmatic calls to PersistentCollection#getIndex; stale or duplicate mappings after partial refactors.
Common situations: Switching a mapping between <bag> and <list> inconsistently; custom framework code driving the collection SPI directly; stale compiled mappings shadowing updated ones.
Related errors
- Bags don't have indexes
- Bag is not a list:
- queued clear cannot be used with orphan delete
- Database doesn't support extracting all indexes at once
- format() function not supported on Sybase
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/61ebc4f251e031c2.
Report an issue: GitHub.