【问题标题】:Why does Hibernate log a different query that it does not actually execute?为什么 Hibernate 会记录一个它实际上并没有执行的不同查询?
【发布时间】:2017-01-13 20:00:00
【问题描述】:

我有一个 Hibernate 查询来检索限制为最大数量的行列表。但是当我阅读 Hibernate 日志时,令我惊讶的是,它在内部过滤了一个子查询,该子查询只有一行 select count(*)

-- Log4j
-- INFO  [STDOUT] Hibernate: 
select *
from ( select count(*) as y0_
       from yyy this_
       where this_.type=3 and
                   this_.VALUE=2 and
                   this_.src='ZZZZZ'
     )
where rownum <= 100;

外部条件是这样的:

criteria.setProjection(Projections.rowCount());
criteria.setMaxResults(MAX_RESULTS); // MAX_RESULTS = 100

final List results = criteria.list(); // It executes the above query here.

对这种行为的解释是什么?我对日志中有更多关于这种误导性结果的查询。

【问题讨论】:

    标签: java hibernate oracle11g log4j


    【解决方案1】:

    您正在设置计数投影。这使得休眠返回计数:

    select count(*) from ...
    

    然后你告诉 Hibernate,虽然没有办法为这样的查询获取多于一行的信息,但将返回的行列表限制为最多 100 行。使用数据库的正确方法是执行 Hibernate 所做的操作:

    select * from ( <original query> ) where rownum <= 100;
    

    如果您不想要那个无用的包装查询,那么就不要调用无用的setMaxResults(100) 方法。

    【讨论】:

    • 我的意思是,setMaxResulst 实际上将检索到的数据过滤了 100。这是必要的。我做了一个内部查询,它有例如 1500 个返回值,所以我需要 100 个过滤器,以免过载。它按预期过滤。但另一方面,Hibernate 对查询的解释不同,就像它只有 1 个 count(*)。我将使用内部查询更新问题。感谢您的及时答复。
    • 执行 select count(*) 的查询,没有任何分组依据,不能返回超过 1 行。它永远不会返回 1500 行。
    • 我将扩展代码,我可能低估了一些代码。
    • 正如我在回答中所说,以及您的问题所示:criteria.setProjection(Projections.rowCount());。这就是告诉 Hibernate 您希望查询计算满足条件的行数,即执行 select count(*)docs.jboss.org/hibernate/orm/current/javadocs/org/hibernate/…
    • 谢谢 JB Nizet。 @Andreas 也阐明了这一点。我们都对(我猜)。首先有一个查询来显示值列表(此查询未显示在日志上。为什么?。而上面的投影用于将 a 值设置为对象(此查询显示在日志上)。作为方法被命名为 listRetrieval,日志只显示无用的查询。我认为 Hibernate 正在将第一个查询(未显示)替换为无用的查询(误导)。
    猜你喜欢
    • 2022-08-11
    • 1970-01-01
    • 2011-12-21
    • 2019-12-09
    • 2023-02-14
    • 2012-02-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多