通过JPA AlgorithtyManager运行多个选择查询时,出现错误“返回多个结果集”

nkoocmlb  于 5个月前  发布在  Go
关注(0)|答案(3)|浏览(59)

为了通过减少多个DB调用来实现更好的性能,我想在同一个DB调用中执行多个select查询。我使用的是PostgreSQL数据库(版本14.9),Java(版本17)和Springboot(版本3.0.6)。
下面是我的代码:

private final EntityManager entityManager;

final List<Object[]> results =
            entityManager.createNativeQuery("select * from roles where role_id <= 200; select * from departments where department_id <= 50")
                .getResultList();

字符串
下面是我得到的错误:

jakarta.persistence.PersistenceException: Converting `org.hibernate.exception.GenericJDBCException` to JPA `PersistenceException` : JDBC exception executing SQL [select * from roles where role_id <= 200; select * from departments where department_id <= 50]
........
........
........
........
........
Caused by: org.hibernate.exception.GenericJDBCException: JDBC exception executing SQL [select * from roles where role_id <= 200; select * from departments where department_id <= 50]
........
........
........
........
........
Caused by: org.postgresql.util.PSQLException: Multiple ResultSets were returned by the query.
    at org.postgresql.jdbc.PgStatement.getSingleResultSet(PgStatement.java:257)
    at org.postgresql.jdbc.PgPreparedStatement.executeQuery(PgPreparedStatement.java:138)
    at org.hibernate.sql.results.jdbc.internal.DeferredResultSetAccess.executeQuery(DeferredResultSetAccess.java:217)


我试了下面的代码:

private final EntityManager entityManager;

final List<Object[]> results =
            entityManager.createNativeQuery("select * from roles where role_id <= 200; select * from departments where department_id <= 50")
                .getResultList();


我期待在“结果”列表对象2结果集。

c2e8gylq

c2e8gylq1#

你已经在给自己制造麻烦了,因为你在没有限制参数的情况下从两个不同的表中选择 *。
您可以创建一个存储过程并选择所需的任何列,也可以执行嵌套的select语句并使用它进行查询。您始终可以获得单个结果集并使用它。参考Spring Boot, JPA / Hibernate: How to execute two raw SELECT queries at once?
但是你所指的性能下降并不是由于多个数据库查询,而是由于没有limit参数的select * 语句。

u7up0aaq

u7up0aaq2#

这不是Hibernate的工作方式,Hibernate不允许你传递一个以上的查询。
如果你真的想这样做,你可以使用UNION ALL。但是我不知道你的rolesdepartment表中的列数是否匹配。
你的方法根本不会起作用,或者即使你使用UNION ALL,这也不是一个好的做法,因为你试图从两个不同的表中获取结果。

wh6knrhe

wh6knrhe3#

对于Hibernate和JPA entityManager,NativeQuery()通常期望单个查询,而不是由一个子对象分隔的多个查询,并且在您的情况下,UNION可能无法工作,因为您正在查询不相互引用的不同实体,但收集主值。
当查询不同的实体以将主条目收集到一个结果集中时,我通常会想到两个选项:

**使用存储过程:**示例存储过程将多个主值(当不可能/不需要关系查询时)收集到一个JSON对象中。这可能会减少您的往返次数。

CREATE OR REPLACE FUNCTION get_department_designation()
RETURNS JSON AS $$
DECLARE
    departments_json json;
    desitnation_json json;
BEGIN
    -- Execute the first query and convert the department result set to JSON
    SELECT json_agg(
    json_build_object(
        'department_id', id,
        'department_name', name
    )
) INTO departments_json FROM my_department WHERE is_active = 1;

    -- Execute the second query and convert the designation result set to JSON
    SELECT json_agg(
    json_build_object(
        'designation_id', id,
        'designation_name', name
    )
) INTO desitnation_json FROM my_designation WHERE is_active = 1;

    -- Combine the two JSON objects into a single object
    RETURN json_build_object(
        'departments', departments_json,
        'designations', desitnation_json
    );
END;
$$ LANGUAGE plpgsql;

字符串
我过去曾多次使用这种方法来查询和收集结果集中的不同实体集。

或者使用JDBC Batch:

Statement statement = connection.createStatement();
statement.addBatch("select * from roles where role_id <= 200");
statement.addBatch("select * from departments where department_id <= 50");
List<ResultSet> resultSets = statement.executeBatch();


(我还没有尝试过,只是一个想法,如果它有帮助)

相关问题