2014-10-30 84 views
2

框架:春季4.0.7和4.3.6的Hibernate如何限制PagingAndSortingRepository @Query中的结果?

我们正与一个PagingAndSortingRepository@Query问题采取的过多时间来完成,因为它似乎是通过记录数据和建筑结构在页面数据分解之前运行限制。

在未加入的情况下,fetch first n rows显示为应该的样子,结果集小得多,使得选择在第一批页面上非常快捷。

我们遇到的最初问题是我们无法对详细记录执行@Queryinner join fetch(强制加入)。删除提取显然让我们脱颖而出,但创建了一个嵌套的SQL循环,这是不可取的。

为了解决这个问题,我们添加了countQuery,它使我们得到了适当的计数,但现在似乎在返回分页结果之前将整个结构加载到内存中。打开调试显示正在加载的记录。尚未添加fetch first n rows

嵌套的SQL在循环中运行对我们来说不是一种选择,因此删除提取并不会有帮助。

@Query(value = "select e from InvoiceHistoryHeader e inner join fetch e.details f where e.company = ?1 and e.division = ?2 and e.customerNumber = ?3)", countQuery = "select count(e) from InvoiceHistoryHeader e where e.company = ?1 and e.division = ?2 and e.customerNumber = ?3)") 
Page<InvoiceHistoryHeader> findByCustomerNumber(String company, String division, String customerNumber, Pageable pageable); 

任何人都可以提供这个问题的解决方案,或提供可能有帮助的解决方法吗?我可以根据需要提供更多细节。

编辑(2014年11月11日)

休眠输出(不获取):

Hibernate: select count(trim(invoicehis0_.HH_TID)) as col_0_0_ from invhh invoicehis0_ where trim(invoicehis0_.HH_CO)=? and trim(invoicehis0_.HH_DIV)=? and trim(invoicehis0_.HH_CUS)=? and trim(invoicehis0_.HH_BR)=? 
Hibernate: select invoicehis0_.hh_tid as hh_tid1_7_, trim(invoicehis0_.HH_CO) as hh_co2_7_, trim(invoicehis0_.HH_CUS) as hh_cus3_7_, trim(invoicehis0_.HH_DTI) as hh_dti4_7_, trim(invoicehis0_.HH_DIV) as hh_div5_7_, trim(invoicehis0_.HH_ORD) as hh_ord6_7_, trim(invoicehis0_.HH_BR) as hh_br7_7_ from invhh invoicehis0_ where trim(invoicehis0_.HH_CO)=? and trim(invoicehis0_.HH_DIV)=? and trim(invoicehis0_.HH_CUS)=? and trim(invoicehis0_.HH_BR)=? fetch first 20 rows only 
Hibernate: select details0_.hd_tid as hd_tid2_7_0_, trim(details0_.HD_SEQ) as hd_seq1_6_0_, trim(details0_.HD_TID) as hd_tid2_6_0_, details0_.hd_seq as hd_seq1_6_1_, details0_.hd_tid as hd_tid2_6_1_, trim(details0_.HD_DTL) as hd_dtl3_6_1_, trim(details0_.HD_LIN) as hd_lin4_6_1_ from invhd details0_ where details0_.hd_tid=? 
Hibernate: select details0_.hd_tid as hd_tid2_7_0_, trim(details0_.HD_SEQ) as hd_seq1_6_0_, trim(details0_.HD_TID) as hd_tid2_6_0_, details0_.hd_seq as hd_seq1_6_1_, details0_.hd_tid as hd_tid2_6_1_, trim(details0_.HD_DTL) as hd_dtl3_6_1_, trim(details0_.HD_LIN) as hd_lin4_6_1_ from invhd details0_ where details0_.hd_tid=? 
<above two SQL repeated 18 more times> 

休眠输出(读取和countQuery):

Hibernate: select invoicehis0_.hh_tid as hh_tid1_7_0_, details1_.hd_seq as hd_seq1_6_1_, details1_.hd_tid as hd_tid2_6_1_, trim(invoicehis0_.HH_CO) as hh_co2_7_0_, trim(invoicehis0_.HH_CUS) as hh_cus3_7_0_, trim(invoicehis0_.HH_DTI) as hh_dti4_7_0_, trim(invoicehis0_.HH_DIV) as hh_div5_7_0_, trim(invoicehis0_.HH_ORD) as hh_ord6_7_0_, trim(invoicehis0_.HH_BR) as hh_br7_7_0_, trim(details1_.HD_DTL) as hd_dtl3_6_1_, trim(details1_.HD_LIN) as hd_lin4_6_1_, details1_.hd_tid as hd_tid2_7_0__, trim(details1_.HD_SEQ) as hd_seq1_6_0__, trim(details1_.HD_TID) as hd_tid2_6_0__ from invhh invoicehis0_ inner join invhd details1_ on trim(invoicehis0_.HH_TID)=details1_.hd_tid where trim(invoicehis0_.HH_CO)=? and trim(invoicehis0_.HH_DIV)=? and trim(invoicehis0_.HH_CUS)=? and trim(invoicehis0_.HH_BR)=? 
+0

我已经添加了我相信你正在寻找的东西。我无法输出fetch连接的计划,因为它包含在'@ Query'中时不会运行。 – ehiggins 2014-11-11 16:52:37

+0

对不起,我对此感到失望。我已经添加了两个计划,第一个没有内部联合抓取,第二个没有限制结果的fetch + countQuery。 – ehiggins 2014-11-11 17:02:17

回答

1

当使用取指在加入并且分页Hibernate进行内存分页,这意味着它将所有记录加载到内存中。 不要在分页中使用提取连接。