{"record":{"id":"7de97b3d083616e0","repo":"hibernate/hibernate-orm","slug":"attribute-s-s-of-type-s-is-annotated-bag","errorCode":null,"errorMessage":"Attribute '%s.%s' of type '%s' is annotated '@Bag' (bags are of type '%s' or '%s')","messagePattern":"Attribute '(.+?)\\.(.+?)' of type '(.+?)' is annotated '@Bag' \\(bags are of type '(.+?)' or '(.+?)'\\)","errorType":"exception","errorClass":"AnnotationException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/boot/model/internal/CollectionBinder.java","lineNumber":947,"sourceCode":"\t\tif ( property.hasAnnotationUsage( OrderColumn.class, modelsContext ) ) {\n\t\t\tthrow new AnnotationException( \"Attribute '\"\n\t\t\t\t\t+ qualify( property.getDeclaringType().getName(), property.getName() )\n\t\t\t\t\t+ \"' is annotated '@Bag' and may not also be annotated '@OrderColumn'\" );\n\t\t}\n\n\t\tif ( property.hasAnnotationUsage( ListIndexBase.class, modelsContext ) ) {\n\t\t\tthrow new AnnotationException( \"Attribute '\"\n\t\t\t\t\t+ qualify( property.getDeclaringType().getName(), property.getName() )\n\t\t\t\t\t+ \"' is annotated '@Bag' and may not also be annotated '@ListIndexBase'\" );\n\t\t}\n\n\t\tfinal var collectionJavaType = property.getType().determineRawClass().toJavaClass();\n\t\tif ( java.util.List.class.equals( collectionJavaType )\n\t\t\t\t|| java.util.Collection.class.equals( collectionJavaType ) ) {\n\t\t\treturn CollectionClassification.BAG;\n\t\t}\n\t\telse {\n\t\t\tthrow new AnnotationException(\n\t\t\t\t\tString.format(\n\t\t\t\t\t\t\tLocale.ROOT,\n\t\t\t\t\t\t\t\"Attribute '%s.%s' of type '%s' is annotated '@Bag' (bags are of type '%s' or '%s')\",\n\t\t\t\t\t\t\tproperty.getDeclaringType().getName(),\n\t\t\t\t\t\t\tproperty.getName(),\n\t\t\t\t\t\t\tcollectionJavaType.getName(),\n\t\t\t\t\t\t\tjava.util.List.class.getName(),\n\t\t\t\t\t\t\tjava.util.Collection.class.getName()\n\t\t\t\t\t)\n\t\t\t);\n\t\t}\n\t}\n\n\tprivate static CollectionClassification determineCollectionClassification(\n\t\t\tClass<?> semanticJavaType,\n\t\t\tMemberDetails property,\n\t\t\tMetadataBuildingContext buildingContext) {\n\t\tif ( semanticJavaType.isArray() ) {","sourceCodeStart":929,"sourceCodeEnd":965,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/boot/model/internal/CollectionBinder.java#L929-L965","documentation":"With @Bag present, the declared Java type of the attribute must be java.util.List or java.util.Collection; those are the only types with bag semantics. CollectionBinder throws this AnnotationException for any other declared raw type (for example java.util.Set), listing the required types in the message.","triggerScenarios":"A property has @Bag, its raw Java class is resolved via property.getType().determineRawClass().toJavaClass(), and that class is neither java.util.List nor java.util.Collection.","commonSituations":"Adding @Bag to a Set-typed attribute while hunting performance issues; switching a collection from List to Set (e.g. to deduplicate) without removing @Bag; custom collection implementations not extending List/Collection.","solutions":["Change the field type to List (or Collection) if bag semantics is intended","Or remove @Bag and keep Set semantics","Do not use custom collection classes with @Bag - only the two JDK interfaces are accepted"],"exampleFix":"// before\n@Bag\nSet<String> tags;   // error: bags are List or Collection\n\n// after\n@Bag\nList<String> tags;  // or remove @Bag to keep Set semantics","handlingStrategy":"validation","validationCode":"// @Bag requires List or Collection declared type\nstatic void checkBagFieldType(Class<?>... entities) {\n    for ( Class<?> c : entities ) {\n        for ( Field f : c.getDeclaredFields() ) {\n            if ( f.isAnnotationPresent( Bag.class ) ) {\n                Class<?> t = f.getType();\n                if ( !List.class.equals( t ) && !Collection.class.equals( t ) ) {\n                    throw new IllegalStateException( \"@Bag on non-List/Collection field \"\n                        + c.getName() + \".\" + f.getName() );\n                }\n            }\n        }\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Declare bag-typed attributes as java.util.List or java.util.Collection, never Set","When changing a field from List to Set, remove @Bag in the same commit","Avoid custom collection implementations in entity mappings - use JDK interfaces"],"tags":["hibernate","bag","collection-type","type-mismatch","annotation-binding"],"backgroundTag":"collection-type-mismatch","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}