hibernate/hibernate-orm · error · UnsupportedOperationException
Bags don't have indexes
Error message
Bags don't have indexes
What it means
getIndex supplies the index of an entry for indexed collections (ordered lists, maps). PersistentIdentifierBag implements it by throwing UnsupportedOperationException because identifier bags have no positional index - elements are identified by their collection id, not by position. The error means an index-dependent code path ran against an id-bag mapping.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/collection/spi/PersistentIdentifierBag.java:319
}
return deletes.iterator();
}
@Override
public boolean hasDeletes(CollectionPersister persister) {
final Map<?,?> snap = (Map<?,?>) getSnapshot();
int deletes = snap.size();
for ( E value : collection ) {
if ( value != null ) {
deletes --;
}
}
return deletes > 0;
}
@Override
public Object getIndex(Object entry, int i, CollectionPersister persister) {
throw new UnsupportedOperationException("Bags don't have indexes");
}
@Override
public Object getElement(Object entry) {
return entry;
}
@Override
public Object getSnapshotElement(Object entry, int i) {
final Map<?,?> snap = (Map<?,?>) getSnapshot();
final Object id = identifiers.get( i );
return snap.get( id );
}
@Override
public boolean needsInserting(Object entry, int i, Type elemType)
throws HibernateException {
final Map<?,?> snap = (Map<?,?>) getSnapshot();View on GitHub (pinned to fad1729dce)
Solutions
- Use a genuinely indexed mapping (<list> / @OrderColumn on a List field) when index access is required
- Keep id-bag mappings for identifier-based semantics and drop positional logic
- Ensure field type and mapping kind match (List for indexed mappings)
- Clean rebuild to rule out stale mapping resources
Example fix
<!-- before -->
<id-bag name="items" table="order_item"> <!-- code expects indexes -->
<!-- after -->
<list name="items" table="order_item">
<key column="order_id"/>
<list-index column="position"/>
</list> Defensive patterns
Strategy: validation
Validate before calling
CollectionPersister cp = sessionFactory.getDomainModel()
.findCollectionDescriptor(Order.class.getName() + ".items");
if (cp == null || !cp.hasIndex()) {
// id-bag: elements identified by collection id, not position; skip index logic
} Type guard
static boolean isIndexedMapping(Field field) {
return field.isAnnotationPresent(OrderColumn.class)
|| Map.class.isAssignableFrom(field.getType());
} Prevention
- Choose <list>/@OrderColumn mappings when positional access is required
- Keep id-bag mappings free of index-based logic
- Clean rebuild after switching collection mapping kinds to avoid stale metadata
When it happens
Trigger: Mapping metadata implying an index (order column / list semantics) while the runtime collection is an identifier bag; programmatic calls to PersistentCollection#getIndex; inconsistent mappings left behind by refactors between list and id-bag.
Common situations: Switching mappings between <list> and <id-bag> without updating all metadata; framework code driving the collection SPI; stale mappings after partial migration.
Related errors
- Bags don't have indexes :
- Bag is not a list:
- Database doesn't support extracting all indexes at once
- format() function not supported on Sybase
- Decomposition not supported for %s
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/2af197441bb26a38.
Report an issue: GitHub.