hibernate/hibernate-orm · error · AnnotationException
Attribute ' ' is annotated '@Bag' and may not also be…
Error message
Attribute '{}' is annotated '@Bag' and may not also be annotated '@OrderColumn' What it means
@Bag explicitly requests unordered BAG semantics, while @OrderColumn implies an ordered LIST backed by an index column. The two contradict each other, so CollectionBinder throws this AnnotationException when both are present on the same attribute.
Solutions
- Remove @OrderColumn if you want bag semantics (unordered, no index column)
- Or remove @Bag so the attribute maps as a LIST with @OrderColumn
- If you only wanted a base for the index, use @ListIndexBase together with @OrderColumn, not @Bag
Example fix
// before @Bag @OrderColumn List<Item> items; // error: bag + order column // after @OrderColumn List<Item> items; // drop @Bag -> LIST with order column // or keep @Bag and remove @OrderColumn for true unordered bag semantics
Defensive patterns
Strategy: validation
Validate before calling
// Reject @Bag combined with @OrderColumn or @ListIndexBase
static void checkBagConflicts(Class<?>... entities) {
for ( Class<?> c : entities ) {
for ( Field f : c.getDeclaredFields() ) {
if ( f.isAnnotationPresent( Bag.class )
&& ( f.isAnnotationPresent( OrderColumn.class )
|| f.isAnnotationPresent( ListIndexBase.class ) ) ) {
throw new IllegalStateException( "@Bag conflicts with an order/index annotation on "
+ c.getName() + "." + f.getName() );
}
}
}
} Prevention
- Decide collection semantics once per attribute: bag (unordered) or list (indexed), never both
- When migrating @LazyCollection(BAG) or legacy mappings to @Bag, strip @OrderColumn and @ListIndexBase
- Add the reflection scan to the mapping test suite
When it happens
Trigger: A property has @Bag and also hasAnnotationUsage(OrderColumn.class) during determineCollectionClassification; the check runs whenever @Bag is present.
Common situations: Adding @Bag to get bag semantics (deduplicated SQL handling, no index maintenance) on a mapping that already carried @OrderColumn; copy-paste of list mappings while switching to bags; version upgrades where legacy @LazyCollection(BAG) mappings were converted to @Bag.
Related errors
- Attribute ' ' is annotated '@Bag' and may not also be…
- Attribute ' . ' of type ' ' is annotated '@Bag' (bags are…
- Collection ' ' is the unowned side of a bidirectional…
- Passed attribute name
- Association ' ' is 'mappedBy' another entity and may not…
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/2b8eb6aa71b8f5b7.
Report an issue: GitHub.
Appendix: source
Thrown at hibernate-core/src/main/java/org/hibernate/boot/model/internal/CollectionBinder.java:930
case SET, ORDERED_SET -> new SetBinder( customTypeBeanAccess, false, buildingContext );
case SORTED_SET -> new SetBinder( customTypeBeanAccess, true, buildingContext );
};
}
private static CollectionClassification determineCollectionClassification(
MemberDetails property,
MetadataBuildingContext buildingContext) {
if ( property.isArray() ) {
return CollectionClassification.ARRAY;
}
final var modelsContext = buildingContext.getBootstrapContext().getModelsContext();
if ( !property.hasAnnotationUsage( Bag.class, modelsContext ) ) {
return determineCollectionClassification( determineSemanticJavaType( property ), property, buildingContext );
}
if ( property.hasAnnotationUsage( OrderColumn.class, modelsContext ) ) {
throw new AnnotationException( "Attribute '"
+ qualify( property.getDeclaringType().getName(), property.getName() )
+ "' is annotated '@Bag' and may not also be annotated '@OrderColumn'" );
}
if ( property.hasAnnotationUsage( ListIndexBase.class, modelsContext ) ) {
throw new AnnotationException( "Attribute '"
+ qualify( property.getDeclaringType().getName(), property.getName() )
+ "' is annotated '@Bag' and may not also be annotated '@ListIndexBase'" );
}
final var collectionJavaType = property.getType().determineRawClass().toJavaClass();
if ( java.util.List.class.equals( collectionJavaType )
|| java.util.Collection.class.equals( collectionJavaType ) ) {
return CollectionClassification.BAG;
}
else {
throw new AnnotationException(
String.format(View on GitHub (pinned to fad1729dce)