hibernate/hibernate-orm · error · AnnotationException

Attribute '{}' is annotated '@Bag' and may not also be annot

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.

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)

Solutions

  1. Remove @OrderColumn if you want bag semantics (unordered, no index column)
  2. Or remove @Bag so the attribute maps as a LIST with @OrderColumn
  3. 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

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


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