{"record":{"id":"6d569082300069cd","repo":"hibernate/hibernate-orm","slug":"selection-item-in-a-multi-select-cannot-contain-co-6d5690","errorCode":null,"errorMessage":"Selection item in a multi-select cannot contain compound tuple-valued elements","messagePattern":"Selection item in a multi-select cannot contain compound tuple-valued elements","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmCriteriaNodeBuilder.java","lineNumber":1339,"sourceCode":"\t * @param selections The selection varargs to check\n\t *\n\t * @throws IllegalArgumentException If the selection items are not valid per\n\t *         according to {@linkplain CriteriaQuery#multiselect this documentation}.\n\t *         <i>&quot;An argument to the multiselect method must not be a tuple-\n\t *         or array-valued compound selection item.&quot;</i>\n\t */\n\tprivate void checkMultiselect(List<? extends Selection<?>> selections) {\n\t\tfinal HashSet<String> aliases = new HashSet<>( determineProperSizing( selections.size() ) );\n\t\tfor ( var selection : selections ) {\n\t\t\tif ( selection.isCompoundSelection() ) {\n\t\t\t\tfinal Class<?> javaType = selection.getJavaType();\n\t\t\t\tif ( javaType.isArray() ) {\n\t\t\t\t\tthrow new IllegalArgumentException(\n\t\t\t\t\t\t\t\"Selection item in a multi-select cannot contain compound array-valued elements\"\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif ( Tuple.class.isAssignableFrom( javaType ) ) {\n\t\t\t\t\tthrow new IllegalArgumentException(\n\t\t\t\t\t\t\t\"Selection item in a multi-select cannot contain compound tuple-valued elements\"\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t\tfinal String alias = selection.getAlias();\n\t\t\tif ( StringHelper.isNotEmpty( alias ) && !aliases.add( alias ) ) {\n\t\t\t\tthrow new IllegalArgumentException( \"Multi-select expressions have duplicate alias '\" + alias + \"'\" );\n\t\t\t}\n\t\t}\n\t}\n\n\t@Nonnull\n\t@Override\n\tpublic <N extends Number> SqmExpression<Double> avg(@Nonnull Expression<N> argument) {\n\t\treturn getFunctionDescriptor( \"avg\" ).generateSqmExpression(\n\t\t\t\t(SqmTypedNode<?>) argument,\n\t\t\t\tnull,\n\t\t\t\tqueryEngine","sourceCodeStart":1321,"sourceCodeEnd":1357,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmCriteriaNodeBuilder.java#L1321-L1357","documentation":"Twin rule of the array variant: multiselect items must not be compound selections whose Java type is Tuple (produced by cb.tuple(...)). The JPA contract forbids tuple- or array-valued compound items as arguments to multiselect because the final row composition is governed by the multiselect call itself, so Hibernate's checkMultiselect rejects them immediately.","triggerScenarios":"query.multiselect(cb.tuple(root.get(\"a\"), root.get(\"b\")), root.get(\"c\")); reusing a helper that returns Selection<Tuple> as one argument of multiselect; migrating a Tuple query into multiselect without unwrapping the tuple(...) wrapper.","commonSituations":"Dynamic report projections assembled from per-column helper methods where one helper already groups columns into a tuple; refactors from query.select(cb.tuple(...)) to multiselect(...).","solutions":["Spread the tuple's arguments into multiselect: multiselect(root.get(\"a\"), root.get(\"b\"), root.get(\"c\")).","Or keep tuple() as the sole top-level selection: query.select(cb.tuple(a, b, c)).","Audit helper methods that return Selection<Tuple>/Selection<Object[]> and stop feeding them to multiselect."],"exampleFix":"// before\nquery.multiselect(cb.tuple(root.get(\"sku\"), root.get(\"name\")), root.get(\"qty\"));\n// -> Selection item in a multi-select cannot contain compound tuple-valued elements\n\n// after\nquery.multiselect(root.get(\"sku\"), root.get(\"name\"), root.get(\"qty\"));","handlingStrategy":"validation","validationCode":"boolean hasNestedTupleItem(List<? extends Selection<?>> items) {\n    for (Selection<?> s : items) {\n        if (s.isCompoundSelection() && Tuple.class.isAssignableFrom(s.getJavaType())) return true;\n    }\n    return false;\n}\nif (hasNestedTupleItem(selections)) throw new IllegalArgumentException(\"flatten tuple() items before multiselect\");","typeGuard":"static boolean isCompoundTupleItem(Selection<?> s) {\n    return s.isCompoundSelection() && Tuple.class.isAssignableFrom(s.getJavaType());\n}","tryCatchPattern":"try {\n    query.multiselect(items);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"tuple-valued\")) { /* spread cb.tuple(...) args into multiselect */ }\n    else throw e;\n}","preventionTips":["Spread tuple components into multiselect; keep tuple() only as the single top-level selection.","When migrating query.select(cb.tuple(...)) code to multiselect, delete the tuple wrapper.","Check helper methods returning Selection<Tuple> before feeding them to multiselect."],"tags":["hibernate","criteria","multiselect","tuple","jpa"],"backgroundTag":"invalid-multiselect-item","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}