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>&quot;An argument to the multiselect method must not be a tuple-
	 *         or array-valued compound selection item.&quot;</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
	@Override

View on GitHub (pinned to fad1729dce)

Solutions

  1. Flatten: pass the individual expressions to multiselect (multiselect(a, b, c)) instead of nesting array(...).
  2. If you really want Object[] rows, use query.select(cb.array(...)) once — not multiselect.
  3. 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

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


AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22). Data as JSON: /api/errors/d4ecc9eaf21ed5e4. Report an issue: GitHub.