簡體   English   中英

JPA / Hibernate似乎將帶有in子句的查詢轉換為帶有=子句的多個查詢

[英]JPA/Hibernate seems to convert a query with an in clause into multiple queries with = clauses

我們實現的解決方案是為了在合理的時間內收集大量重物並且沒有內存溢出(我說的是具有多個fetchType.eager關系的對象,對於本身具有渴望獲取的關系的實體),首先選擇id這些對象,然后根據這些ID選擇對象。

花時間優化我們的代碼,我們注意到(使用hibernate.show_sql=true )我們用於收集這些對象的查詢( select a from A a where a.id in :ids )由JPA / Hibernate轉換成數千個表單的查詢select a from ...endless join list... where a.id = ?

問題如下:

為什么JPA / Hibernate使用“in”子句將我們的初始查詢轉換為帶有“=”子句的許多查詢。 這不是無效嗎? 如果是這樣,有沒有辦法防止這種情況?

以下是我們的代碼中調用查詢的方式:

    Query q = this.getContext().createQuery("select a from A a where a.id in :ids");
    q.setParameter("ids", idList);
    return (List<A>) q.getResultList();

您好,您應該使用setParameterList而不是setParameter 如果你想獲得完整的實體對象,也不需要在hibernate中使用select

 Query q = this.getContext().createQuery("from A a where a.id in (:ids)");
q.setParameterList("ids", idList);
return (List<A>) q.getResultList();

如果你的idList超過1000個元素,你可能會遇到這個特定於Oracle的去優化https://hibernate.atlassian.net/browse/HHH-9299

解決此問題的一種方法是將idList分解為多個塊,對每個塊執行查詢並連接結果。

雖然我仍然無法解釋為什么為in子句中提供的每個ID生成查詢(在我原來的問題中提供),但我在這個博客上找到了解決這個問題的方法( https://thoughts-on-java.org / fetch-multiple-entities-id-hibernate / )。 解決方案包括使用Hibernate的會話API,如下所示:

//get session object from entity manager
Session session = em.unwrap(Session.

MultiIdentifierLoadAccess<A> multiLoadAccess = session.byMultipleIds(A.class);
List<A> aObjects= multiLoadAccess.withBatchSize(1000).multiLoad(idList);
return aObjects;

暫無
暫無

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

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