{"record":{"id":"21b8c3a6ae49f964","repo":"hibernate/hibernate-orm","slug":"domain-result-for-non-scalar-subquery-shouldn-t-be","errorCode":null,"errorMessage":"Domain result for non-scalar subquery shouldn't be created","messagePattern":"Domain result for non-scalar subquery shouldn't be created","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/sql/ast/tree/select/SelectStatement.java","lineNumber":96,"sourceCode":"\t\t\tfinal SqlSelection first = sqlSelections.get( 0 );\n\t\t\tfinal JdbcMapping jdbcMapping = first.getExpressionType().getSingleJdbcMapping();\n\t\t\tfinal SqlSelection sqlSelection =\n\t\t\t\t\tcreationState.getSqlAstCreationState().getSqlExpressionResolver()\n\t\t\t\t\t\t\t.resolveSqlSelection(\n\t\t\t\t\t\t\t\t\tthis,\n\t\t\t\t\t\t\t\t\tjdbcMapping.getJdbcJavaType(),\n\t\t\t\t\t\t\t\t\tnull,\n\t\t\t\t\t\t\t\t\tcreationState.getSqlAstCreationState().getCreationContext()\n\t\t\t\t\t\t\t\t\t\t\t.getTypeConfiguration()\n\t\t\t\t\t\t\t);\n\t\t\treturn new BasicResult<>(\n\t\t\t\t\tsqlSelection.getValuesArrayPosition(),\n\t\t\t\t\tresultVariable,\n\t\t\t\t\tjdbcMapping\n\t\t\t);\n\t\t}\n\t\telse {\n\t\t\tthrow new UnsupportedOperationException(\"Domain result for non-scalar subquery shouldn't be created\");\n\t\t}\n\t}\n\n\t@Override\n\tpublic void applySqlSelections(DomainResultCreationState creationState) {\n\t\tfinal TypeConfiguration typeConfiguration =\n\t\t\t\tcreationState.getSqlAstCreationState().getCreationContext()\n\t\t\t\t\t\t.getTypeConfiguration();\n\t\tfinal SqlExpressionResolver expressionResolver =\n\t\t\t\tcreationState.getSqlAstCreationState().getSqlExpressionResolver();\n\t\tfor ( SqlSelection sqlSelection :\n\t\t\t\tqueryPart.getFirstQuerySpec().getSelectClause().getSqlSelections() ) {\n\t\t\tsqlSelection.getExpressionType().forEachJdbcType(\n\t\t\t\t\t(index, jdbcMapping) -> {\n\t\t\t\t\t\texpressionResolver\n\t\t\t\t\t\t\t\t.resolveSqlSelection(\n\t\t\t\t\t\t\t\t\t\tthis,\n\t\t\t\t\t\t\t\t\t\tjdbcMapping.getJdbcJavaType(),","sourceCodeStart":78,"sourceCodeEnd":114,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/select/SelectStatement.java#L78-L114","documentation":"SelectStatement.createDomainResult builds a DomainResult when a subquery SelectStatement is used as a scalar expression. It only supports subqueries whose first QuerySpec has exactly one SqlSelection; anything else - multiple select items, or a single entity/composite selection that expands to several SQL selections - throws UnsupportedOperationException('Domain result for non-scalar subquery shouldn't be created').","triggerScenarios":"HQL/Criteria where a subquery occupies a scalar position (comparison, select item, function argument) but selects more than one thing: 'where e.age > (select e1.age, e1.id from Employee e1)', 'select (select e1 from Employee e1) from ...', or a subquery selecting an entity/embeddable. SQM translators building domain results for expression-position subqueries.","commonSituations":"Porting SQL tuple comparisons '(a,b) = (select x,y ...)' to HQL; subqueries selecting a whole entity instead of one column; Criteria Subquery multiselect used inside a where expression; stricter enforcement surfacing after migrating to Hibernate 6.","solutions":["Reduce the subquery to exactly one select item (one column or basic expression)","Select a single attribute (e.g. the id) instead of the whole entity in the subquery","Rewrite tuple comparisons as an exists() subquery or AND-ed scalar comparisons","In Criteria, use a single-valued Subquery<Long>/Expression rather than multiselect"],"exampleFix":"// before (HQL)\nwhere e.age > ( select e1.age, e1.id from Employee e1 where e1.dept = e.dept )\n\n// after\nwhere e.age > ( select max(e1.age) from Employee e1 where e1.dept = e.dept )","handlingStrategy":"validation","validationCode":"// JPQL/HQL: keep subqueries in scalar positions single-item\nString hql = \"where e.age > ( select max(e1.age) from Employee e1 where e1.dept = e.dept )\";","typeGuard":null,"tryCatchPattern":"try {\n    return session.createQuery( hql, Integer.class ).getSingleResult();\n} catch ( UnsupportedOperationException e ) {\n    if ( e.getMessage() != null && e.getMessage().contains( \"non-scalar subquery\" ) ) {\n        throw new IllegalArgumentException( \"Subquery must select exactly one value: \" + hql, e );\n    }\n    throw e;\n}","preventionTips":["Keep every subquery used as an expression down to exactly one select item","Select the id or a single attribute instead of an entity in scalar subqueries","Replace SQL tuple comparisons with exists() or AND-ed comparisons when moving to HQL"],"tags":["hibernate","orm","hql","criteria","subquery","sql-ast"],"backgroundTag":"non-scalar-subquery-unsupported","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}