{"record":{"id":"5dace476b200e9c1","repo":"hibernate/hibernate-orm","slug":"passed-attribute-name-s-did-not-correspond-to-a","errorCode":null,"errorMessage":"Passed attribute name [%s] did not correspond to a collection (bag) reference [%s] relative to %s","messagePattern":"Passed attribute name \\[(.+?)\\] did not correspond to a collection \\(bag\\) reference \\[(.+?)\\] relative to (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/query/sqm/tree/spi/domain/AbstractSqmFrom.java","lineNumber":539,"sourceCode":"\t\treturn joinCollection( attributeName, JoinType.INNER );\n\t}\n\n\t@Nonnull\n\t@Override\n\t@SuppressWarnings(\"unchecked\")\n\tpublic <Y> SqmBagJoin<T, Y> joinCollection(@Nonnull String attributeName, @Nonnull JoinType jt) {\n\t\tfinal var joinedPathSource = getReferencedPathSource().getSubPathSource( attributeName );\n\t\tif ( joinedPathSource instanceof BagPersistentAttribute ) {\n\t\t\tfinal var join = buildBagJoin(\n\t\t\t\t\t(BagPersistentAttribute<T, Y>) joinedPathSource,\n\t\t\t\t\tSqmJoinType.from( jt ),\n\t\t\t\t\tfalse\n\t\t\t);\n\t\t\taddSqmJoin( join );\n\t\t\treturn join;\n\t\t}\n\n\t\tthrow new IllegalArgumentException(\n\t\t\t\tString.format(\n\t\t\t\t\t\tLocale.ROOT,\n\t\t\t\t\t\t\"Passed attribute name [%s] did not correspond to a collection (bag) reference [%s] relative to %s\",\n\t\t\t\t\t\tattributeName,\n\t\t\t\t\t\tjoinedPathSource,\n\t\t\t\t\t\tgetNavigablePath()\n\t\t\t\t)\n\t\t);\n\t}\n\n\t@Nonnull\n\t@Override\n\tpublic <Y> SqmSetJoin<T, Y> joinSet(@Nonnull String attributeName) {\n\t\treturn joinSet( attributeName, JoinType.INNER );\n\t}\n\n\t@Nonnull\n\t@Override","sourceCodeStart":521,"sourceCodeEnd":557,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/spi/domain/AbstractSqmFrom.java#L521-L557","documentation":"AbstractSqmFrom.joinCollection(attributeName, joinType) resolves the attribute via getSubPathSource(attributeName) and requires it to be a BagPersistentAttribute (a Collection/bag mapping). If the attribute exists but is a Set, List, Map or singular attribute, Hibernate throws IllegalArgumentException showing the attribute name, the resolved path source and the navigable path.","triggerScenarios":"root.joinCollection(\"orders\", JoinType.INNER) when orders is mapped as java.util.Set, java.util.List (with @OrderColumn) or java.util.Map; joinCollection on a @ManyToOne/@Basic attribute.","commonSituations":"Changing an entity field from List to Set between versions while the query code still calls joinCollection; generic query helpers that always use joinCollection for any plural attribute; a List field mapped without @OrderColumn is a bag in Hibernate and works, but a Set field does not.","solutions":["Use the join method matching the mapping: joinSet for Set, joinList for ordered List, joinMap for Map, join/join(entityType) for singular associations.","Prefer the metamodel-typed overloads join(CollectionAttribute), join(SetAttribute), etc., which are compile-time safe.","Check the attribute kind via the metamodel before choosing the join method in generic code."],"exampleFix":"// before\nSqmBagJoin<Customer, Order> o = customerRoot.joinCollection( \"orders\", JoinType.LEFT ); // orders is a Set\n// after\nSqmSetJoin<Customer, Order> o = customerRoot.joinSet( \"orders\", JoinType.LEFT );","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"static boolean isBag(ManagedType<?> type, String attr) {\n    return type.getAttribute( attr ) instanceof jakarta.persistence.metamodel.PluralAttribute<?, ?, ?> p\n        && p.getCollectionType() == jakarta.persistence.metamodel.PluralAttribute.CollectionType.COLLECTION;\n}","tryCatchPattern":null,"preventionTips":["Prefer metamodel-typed overloads join(CollectionAttribute)/join(SetAttribute)/... which cannot mismatch.","In generic code, switch on PluralAttribute.getCollectionType() before picking joinCollection/joinSet/joinList/joinMap.","After changing an entity field's container type, update every string-based join call for that attribute."],"tags":["hibernate","criteria-api","join","collection","illegal-argument"],"backgroundTag":"wrong-collection-join-type","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}