簡體   English   中英

使用ScrollableResults渴望在Hibernate中獲取集合

[英]Eager fetching collections in Hibernate with ScrollableResults

我正在嘗試使用Hibernate從表中檢索大約1億行。 我有一個持久化的實體項目,其中包含一個費用集合(另一個持久化實體)。 鑒於我迭代結果並訪問每個對象的費用,我想急切地獲取費用以避免n + 1問題。

我還要提一下,我想將它加入另一個名為Provider的表(一對一映射但沒有外鍵)。 我試過了:

String query = "select new " + Order.class.getName() 
           + "(i, p) from Item i left join fetch i.fees f, Provider p where "
           + "p.factoryId=i.factoryId and p.factoryRef=i.factoryRef";

return session.createQuery(query).scroll();

我的Order類包含Provider字段和Item字段。 我收到此錯誤:

引起:org.hibernate.QueryException:查詢指定的連接提取,但選擇列表中不存在獲取的關聯的所有者

我想最終得到一個可滾動的Order列表,其中包含Item(收取費用)和Provider。

SelectClause代碼SelectClause您帶來麻煩:

if ( !fromElementsForLoad.contains( origin ) ) {
                        throw new QueryException(
                                "query specified join fetching, but the owner " +
                                "of the fetched association was not present in the select list " +
                                "[" + fromElement.getDisplayText() + "]"
                        );

如您所見,當提到fetch關鍵字時,hibernate會檢查您是否要求提取裝飾字段parent。 fromElementsForLoad.contains( origin )

他們可能會這樣做是為了防止你進行冗余連接,這會使你在性能上花費很多。 這是一件好事,因為如果你從不使用它,就沒有理由獲取關聯。

我相信在你的情況下 - 在新的Item.class中包裝Order.class隱藏你在查詢中使用fetch decorated字段parent的事實。

我目前沒有調試功能,所以我無法驗證這一點。 嘗試從SelectClause.class調試這個確切的行,看看fromElementsForLoad集合中包含哪些元素。

如果你想避免n + 1問題,我建議在查詢后初始化Order.class。 您只能選擇項目和提供者。

如果你無法驗證這一點,我將在下周找到合適的電腦並擴展我的答案。

嘗試刪除left join fetch i.fees f並在映射中執行急切提取。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM