{"record":{"id":"034ef77bac2357b3","repo":"hibernate/hibernate-orm","slug":"cannot-access-the-type-of-plural-valued-simple-pat","errorCode":null,"errorMessage":"Cannot access the type of plural valued simple paths","messagePattern":"Cannot access the type of plural valued simple paths","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/query/sqm/tree/spi/domain/SqmPluralValuedSimplePath.java","lineNumber":219,"sourceCode":"\t\t\t\t\tSqmJoinType.INNER,\n\t\t\t\t\tfalse,\n\t\t\t\t\tnodeBuilder()\n\t\t\t);\n\t\t\tindex = ( (SqmMapJoin<?, ?, ?>) join).key();\n\t\t}\n\t\telse {\n\t\t\tthrow new NotIndexedCollectionException( \"Index operator applied to path '\" + getNavigablePath()\n\t\t\t\t\t+ \"' which is not a list or map\" );\n\t\t}\n\t\tjoin.setJoinPredicate( nodeBuilder().equal( index, selector ) );\n\t\tparent.addSqmJoin( join );\n\t\treturn join;\n\t}\n\n\t@Nonnull\n\t@Override\n\tpublic SqmExpression<Class<? extends C>> type() {\n\t\tthrow new UnsupportedOperationException( \"Cannot access the type of plural valued simple paths\" );\n\t}\n\n\t@Nonnull\n\t@Override\n\tpublic <S extends C> SqmTreatedPath<C, S> treatAs(@Nonnull Class<S> treatJavaType) {\n\t\tthrow new UnsupportedOperationException( \"Cannot treat plural valued simple paths\" );\n\t}\n\n\t@Nonnull\n\t@Override\n\tpublic <S extends C> SqmTreatedEntityValuedSimplePath<C, S> treatAs(@Nonnull EntityDomainType<S> treatTarget) {\n\t\tthrow new UnsupportedOperationException( \"Cannot treat plural valued simple paths\" );\n\t}\n\n\t@Nonnull\n\t@Override\n\tpublic SqmPredicate isEmpty() {\n\t\treturn new SqmEmptinessPredicate( this, false, nodeBuilder() );","sourceCodeStart":201,"sourceCodeEnd":237,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/spi/domain/SqmPluralValuedSimplePath.java#L201-L237","documentation":"The JPA TYPE operator returns the discriminator of an entity-valued path. A plural-valued path (the collection reference itself, as opposed to its elements) denotes many values and has no single discriminator, so SqmPluralValuedSimplePath.type() unconditionally throws UnsupportedOperationException. TYPE must be applied to an entity-valued path, typically the joined element of the collection.","triggerScenarios":"HQL 'select type(p.orders) from Person p' or 'where type(o.lines) = SpecialLine' where 'orders'/'lines' are @OneToMany/@ManyToMany; criteria code calling path.get(\"lines\").type() or builder.type(...) on a plural path; any .type() call on a path whose referenced source is a PluralPersistentAttribute.","commonSituations":"Polymorphic collections where the developer wants the concrete class per element; copy-pasting a working type(o) expression from an entity path onto a collection path; discriminator filters ported from SQL CASE expressions.","solutions":["Join the collection and apply type() to the joined entity alias: 'select type(l) from Order o join o.lines l'","Use element() to reference the collection contents before applying type(): 'type(element(o.lines))'","For @ElementCollection of basic/embeddable values, TYPE has no meaning at all: select an explicit discriminator property instead"],"exampleFix":"// before\nselect o from Order o where type(o.lines) = SpecialLine\n\n// after\nselect o from Order o join o.lines l where type(l) = SpecialLine","handlingStrategy":"type-guard","validationCode":"if (path.getReferencedPathSource() instanceof org.hibernate.metamodel.model.domain.PluralPersistentAttribute<?, ?, ?>) {\n    // apply type() to the joined element instead of this path\n}","typeGuard":"static boolean isEntityTypePath(SqmPath<?> path) {\n    return !(path.getReferencedPathSource()\n        instanceof org.hibernate.metamodel.model.domain.PluralPersistentAttribute<?, ?, ?>);\n}","tryCatchPattern":"try {\n    expression = path.type();\n} catch (UnsupportedOperationException e) {\n    // plural path: join the collection and call type() on the join\n}","preventionTips":["Reserve type() for entity aliases obtained from FROM/JOIN","Never apply TYPE to @ElementCollection paths; select an explicit discriminator property","Review queries that mix polymorphic collections with TYPE"],"tags":["hibernate","hql","sqm","type-operator","polymorphism","collection-mapping"],"backgroundTag":"type-operator-on-non-entity-path","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}