You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用JPA EntityManager执行多查询时遇“Multiple ResultSets were returned”错误

解决PostgreSQL中单次调用执行多条SELECT查询获取多结果集的问题

错误原因

你遇到的Multiple ResultSets were returned by the query异常,核心原因是JPA的EntityManager.createNativeQuery().getResultList()默认仅支持处理单个结果集,但你执行的SQL返回了两个独立的结果集(roles和departments),超出了它的处理范围。PostgreSQL本身支持批量执行多条SQL,但JPA的封装层未提供直接处理多结果集的API。

解决方案

以下是适配你技术栈(PostgreSQL 14.9、Java 17、Spring Boot 3.0.6)的可行方案:

方案1:使用原生JDBC直接处理多结果集

绕过JPA封装,直接通过JDBC API执行SQL并手动遍历多个结果集,这种方式完全可控:

import jakarta.persistence.EntityManager;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

// 注入EntityManager
private final EntityManager entityManager;

public void fetchMultipleResults() {
    List<List<Object[]>> allResults = new ArrayList<>();
    Statement statement = null;
    ResultSet resultSet = null;

    try {
        // 从EntityManager获取JDBC连接(由Spring管理,无需手动关闭)
        Connection connection = entityManager.unwrap(Connection.class);
        statement = connection.createStatement();
        // 执行批量SQL
        boolean hasMoreResults = statement.execute("select * from roles where role_id <= 200; select * from departments where department_id <= 50");

        do {
            resultSet = statement.getResultSet();
            List<Object[]> resultList = new ArrayList<>();
            int columnCount = resultSet.getMetaData().getColumnCount();
            // 遍历当前结果集的每一行
            while (resultSet.next()) {
                Object[] row = new Object[columnCount];
                for (int i = 0; i < columnCount; i++) {
                    row[i] = resultSet.getObject(i + 1);
                }
                resultList.add(row);
            }
            allResults.add(resultList);
            // 检查是否有下一个结果集
            hasMoreResults = statement.getMoreResults();
        } while (hasMoreResults || statement.getUpdateCount() != -1);

    } catch (Exception e) {
        throw new RuntimeException("批量查询失败", e);
    } finally {
        // 手动关闭ResultSet和Statement
        try { if (resultSet != null) resultSet.close(); } catch (Exception e) {}
        try { if (statement != null) statement.close(); } catch (Exception e) {}
    }

    // allResults[0]是roles的结果,allResults[1]是departments的结果
}

注意:不要手动关闭Connection,它由Spring的EntityManager管理,会在事务结束后自动回收。

方案2:使用Spring JdbcTemplate处理多结果集

如果项目已引入Spring JdbcTemplate,它提供了更简洁的多结果集处理API:

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.ResultSetExtractor;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

// 注入JdbcTemplate
private final JdbcTemplate jdbcTemplate;

public List<List<Object[]>> fetchMultipleResults() {
    String sql = "select * from roles where role_id <= 200; select * from departments where department_id <= 50";

    return jdbcTemplate.query(sql, (ResultSetExtractor<List<List<Object[]>>>) rs -> {
        List<List<Object[]>> allResults = new ArrayList<>();
        do {
            List<Object[]> resultList = new ArrayList<>();
            int columnCount = rs.getMetaData().getColumnCount();
            while (rs.next()) {
                Object[] row = new Object[columnCount];
                for (int i = 0; i < columnCount; i++) {
                    row[i] = rs.getObject(i + 1);
                }
                resultList.add(row);
            }
            allResults.add(resultList);
        } while (rs.getStatement().getMoreResults());
        return allResults;
    });
}

JdbcTemplate会自动处理资源的打开与关闭,无需手动管理。

方案3:表结构兼容时使用UNION ALL合并结果

如果roles和departments的字段数量、类型可兼容(比如都包含id、名称等字段),可以用UNION ALL合并成单个结果集,再通过标识字段区分数据来源:

final List<Object[]> results = entityManager.createNativeQuery(
    "select 'role' as data_type, * from roles where role_id <= 200 " +
    "union all " +
    "select 'dept' as data_type, * from departments where department_id <= 50"
).getResultList();

限制:两个查询的字段数量必须一致,对应位置的字段类型需兼容,否则会触发SQL语法错误。此方式仅适合结构相似的表查询。

内容的提问来源于stack exchange,提问作者ParthDobariya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 12:06:12