hibernate/hibernate-orm · error · IllegalArgumentException
Selection item in a multi-select cannot contain compound arr
Error message
Selection item in a multi-select cannot contain compound array-valued elements
What it means
CriteriaQuery.multiselect validates each selection item per the JPA spec: an argument to multiselect must not itself be a tuple- or array-valued compound selection. checkMultiselect throws IllegalArgumentException when a compound selection item (built by cb.array(...)) whose Java type is an array is nested inside multiselect — the resulting row shape would be ambiguous.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmCriteriaNodeBuilder.java:1334
/**
* Check the arguments of {@link jakarta.persistence.criteria.CriteriaBuilder#array},
* {@link jakarta.persistence.criteria.CriteriaBuilder#construct}, or
* {@link jakarta.persistence.criteria.CriteriaBuilder#tuple}.
*
* @param selections The selection varargs to check
*
* @throws IllegalArgumentException If the selection items are not valid per
* according to {@linkplain CriteriaQuery#multiselect this documentation}.
* <i>"An argument to the multiselect method must not be a tuple-
* or array-valued compound selection item."</i>
*/
private void checkMultiselect(List<? extends Selection<?>> selections) {
final HashSet<String> aliases = new HashSet<>( determineProperSizing( selections.size() ) );
for ( var selection : selections ) {
if ( selection.isCompoundSelection() ) {
final Class<?> javaType = selection.getJavaType();
if ( javaType.isArray() ) {
throw new IllegalArgumentException(
"Selection item in a multi-select cannot contain compound array-valued elements"
);
}
if ( Tuple.class.isAssignableFrom( javaType ) ) {
throw new IllegalArgumentException(
"Selection item in a multi-select cannot contain compound tuple-valued elements"
);
}
}
final String alias = selection.getAlias();
if ( StringHelper.isNotEmpty( alias ) && !aliases.add( alias ) ) {
throw new IllegalArgumentException( "Multi-select expressions have duplicate alias '" + alias + "'" );
}
}
}
@Nonnull
@OverrideView on GitHub (pinned to fad1729dce)
Solutions
- Flatten: pass the individual expressions to multiselect (multiselect(a, b, c)) instead of nesting array(...).
- If you really want Object[] rows, use query.select(cb.array(...)) once — not multiselect.
- For typed wrappers use multiselect with a construct()/tuple only at the top level, never nested.
Example fix
// before
query.multiselect(cb.array(root.get("sku"), root.get("name")), root.get("qty"));
// -> Selection item in a multi-select cannot contain compound array-valued elements
// after
query.multiselect(root.get("sku"), root.get("name"), root.get("qty")); Defensive patterns
Strategy: validation
Validate before calling
boolean validMultiselect(List<? extends Selection<?>> items) {
for (Selection<?> s : items) {
if (s.isCompoundSelection() && s.getJavaType() != null && s.getJavaType().isArray()) return false;
}
return true;
}
if (!validMultiselect(selections)) throw new IllegalArgumentException("flatten array() items before multiselect"); Type guard
static boolean isCompoundArrayItem(Selection<?> s) {
return s.isCompoundSelection() && s.getJavaType() != null && s.getJavaType().isArray();
} Try / catch
try {
query.multiselect(items);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("array-valued")) { /* flatten cb.array(...) items into individual expressions */ }
else throw e;
} Prevention
- Treat multiselect arguments as a flat list of scalar/composite items; never nest array(...).
- Use query.select(cb.array(...)) when Object[] rows are the goal.
- Audit dynamic-projection helpers that append prebuilt Selection<Object[]> items.
When it happens
Trigger: query.multiselect(cb.array(root.get("a"), root.get("b")), root.get("c")) — cb.array produces a compound selection typed Object[], which is rejected; also passing a selection produced by another array() call (e.g. a shared helper returning Selection<Object[]>) into multiselect.
Common situations: Copy-pasting an existing 'select as array' helper into a multiselect-based projection; refactoring query.select(cb.array(...)) into multiselect(...) without flattening; building dynamic column lists where an array group is appended as one item.
Related errors
- Selection item in a multi-select cannot contain compound tup
- Unable to unwrap to {}
- Multi-select expressions have duplicate alias '{}'
- empty selections passed to criteria query typed as Object
- Informix does not support binary literals
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/d4ecc9eaf21ed5e4.
Report an issue: GitHub.