所以,我有一個相當複雜的查詢,我試圖使用Hibernate Criteria API。我有以下實體類:休眠標準限制選擇
代碼
禮品
GiftVendor
GiftVendorStatus
有以下關係:
碼1 <> 1禮品
禮品1 <> * GiftVendor
GiftVendor 1 <> 1個GiftVendorStatus
我需要建立一個標準查詢,返回代碼對象的名單,但是它限制了有一個禮物,至少有一個GiftVendor用的GiftVendorStatus唯一代碼線上。這裏是我用來建立標準的代碼:
Criteria base = CodeDao.getBaseCriteria();
base.createAlias("gift","gift");
base.createAlias("gift.giftVendor","giftVendor");
base.createAlias("giftVendor.giftVendorStatus","giftVendorStatus");
base.add(Restrictions.like("giftVendorStatus.description", "Online%"));
return base.list();
這給了我一個代碼對象列表,如我所期望的那樣受限制。但是,它還會執行附加查詢來構建Gift對象的所有未使用關係,即使我已將所有映射設置爲Lazy的獲取模式。這會爲我的每個10000+個結果增加4個額外的單獨查詢。
我有代碼來執行使用HQL按預期工作查詢:
String hql = "select c FROM Code c inner join c.gift g inner join g.giftVendors gv inner join gv.giftVendorStatus gvs" +
" WHERE gvs.description like :desc";
HashMap<String,Object> params = new HashMap<String, Object>();
params.put("desc", "Online%");
return performQuery(hql, params);
該代碼給我的代碼對象的名單,不出所料,沒有做所有額外的查詢來填充送禮對象。我如何告訴Hibernate不要使用Criteria API執行這些額外的查詢?
更新:這裏的問題不是禮品表的檢索,而是禮品表中不相關的一對一關係。例如,Gift與GiftCommentAggregateCache具有一對一的關係。此表與此特定查詢無關,所以我期望應用懶惰初始化規則,並且除非嘗試讀取,否則不會發生對GiftCommentAggregateCache的查詢。但是,通過如上所述寫出Criteria查詢,它將使該單獨查詢爲GiftCommentAggregateCache填充模型對象。
如果我使用:
base.setFetchMode("gift.giftCommentAggregateCache", FetchMode.JOIN);
那麼我沒有任何問題。然而,這意味着爲了讓這個工作像我期望的那樣,我需要爲Gift中每一個未使用的一對一關係添加一行。關於爲什麼在映射中指定的延遲規則不在這裏發揮作用的任何想法?
有一些不同的東西我曾嘗試:
base.setFetchMode("gift", FetchMode.LAZY); // Still does additional queries
和
base.setFetchMode("gift", FetchMode.SELECT); // Still does additional queries
和
base.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY); // Still does additional queries
和
base.setResultTransformer(Criteria.ROOT_ENTITY); // Still does additional queries
和
base.setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP); // Still does additional queries
和
儘管這裏指定的具體建議並未解決問題,但它確實指出了我如何解決問題的正確方向。我用新的結果更新了我的問題。但是,這仍然不太合適,因爲我必須爲我的Gift對象中的所有一對一映射添加該行,此時應該應用默認映射。 – 2011-02-25 00:56:28