問題是我在我的實體中有兩個包,我想顯示在我的jsf前端(後面的Spring中沒有延遲加載)。所以,我必須預先抓取它們顯示在這樣的列表中的信息:休眠獲取加入 - >無法獲取多個包
- 1點(標籤1,標籤2)(Tag1中...標籤N)
- 點2(標籤3,標籤4)(Tag1 ... Tag n)
把這兩個列表都渴望沒有工作。所以我嘗試了一個fetch連接。它允許我獲取一個列表,但是當我添加第二個列表時,我得到已知的「無法取多個行李」錯誤。
Hibernate可以處理查詢中的兩個提取連接嗎?
public class PointOfInterest
@OneToMany(mappedBy="poi")
private List<PointOfInterestLabel> labels = new ArrayList<PointOfInterestLabel>();
@ManyToMany
private List<Tag> tags = new ArrayList<Tag>();
我的抓取連接:
SELECT DISTINCT p from PointOfInterest p
left join fetch p.labels
left join fetch p.tags WHERE p.figure = :figure
在啓動時創建我的休眠廠的失敗:
Caused by: org.hibernate.loader.MultipleBagFetchException: cannot simultaneously fetch multiple bags
at org.hibernate.loader.BasicLoader.postInstantiate(BasicLoader.java:94)
at org.hibernate.loader.hql.QueryLoader.<init>(QueryLoader.java:123)
at org.hibernate.hql.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:206)
at org.hibernate.hql.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:136)
at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:101)
at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:80)
at org.hibernate.engine.query.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:98)
at org.hibernate.impl.SessionFactoryImpl.checkNamedQueries(SessionFactoryImpl.java:557)
at org.hibernate.impl.SessionFactoryImpl.<init>(SessionFactoryImpl.java:422)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1385)
at org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:954)
at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:883)
... 55 more
謝謝!目前我用Set取代它,但我想我會重構明天的界面並顯示更少的信息。感謝您的反饋!當你的前端沒有持久化範圍時,你會如何解決它。使用DAO中構建的數據傳輸對象而不是獲取的實體?我繼承了這個項目,並且我不允許進行巨大的設計更改,也不允許將其切換到j2ee。 : -/ – mkuff
您可以關閉延遲加載,這對性能不利。這通過單獨的查詢立即提取行李。你也可以訪問袋子(如尺寸)來強制裝載。完美的解決方案是在dao之外創建會話並保留整個業務事務。 (在每次調用dao時創建一個會話稱爲session-per-call,並且是一種反模式。) –
所以真的這是一個catch 22問題:如果你不使用join提取,你會得到n + 1問題或者延遲初始化異常。在Dao之外的會話是一種破解,首先因爲它遠不及JPA合同,其次是因爲它幾乎不可控,因爲在創建實體時不應該對實體的生命週期做出任何假設。它可能跨越多個請求,不一定是http。 – Deroude