2010-01-27 79 views
1

我有一個項目列表。每個項目都有一組類別。我想抓住特定類別的所有項目。這部分很簡單。我遇到問題的部分是讓我的查詢返回所有類別的項目,而不僅僅是我過濾的項目。休眠查詢不返回完整對象

 
session.createCriteria(Item.class) 
     .createAlias("categories","category") 
     .add(Restrictions.eq("category.name",categoryFilter)) 

上面的代碼返回的項目,但只與我過濾的類別。無論如何要說這個限制過濾對象,但返回完整的對象,而不是過濾的對象?我也試着用HQL編寫這個結果。

回答

3

看來真的是FetchMode和createAlias,之間的一些討厭的相互作用,其看起來像一個bug給我。

有一些關於https://forums.hibernate.org/viewtopic.php?t=944439的討論,其中一位開發者強烈地指出這是正確的行爲,不會被修復。

雖然討論也包含潛在的解決方法。

嘗試使用嵌套的標準,而不是一個別名:

session.createCriteria(Item.class) 
    .createCriteria("categories") 
     .add(Restrictions.eq("name",categoryFilter)) 

隨着集合映射爲渴望,這似乎爲我工作。不確定與在外部條件下使用FetchMode的交互。

0

這可能與使用別名和限制沒有太大關係,但僅僅是默認延遲獲取的結果。

在Item的映射中,您可能會將類別設置爲延遲獲取,這是默認設置,通常是一個好主意。

您可以將此映射更改爲渴望,但這可能是一個壞主意。

離開默認提取懶惰而做出的具體標準檢索熱切,您可以設置讀取模式那裏,類似的東西

session.createCriteria(Item.class) 
    .setFetchMode("categories", FetchMode.EAGER) 
    .createAlias("categories","category") 
    .add(Restrictions.eq("category.name",categoryFilter)) 
+1

我已經雙重檢查了渴望的映射,並且已經設置了fetchmode,如您所示。它們都沒有成功。 – UmYeah 2010-01-30 05:04:25

+0

我現在已經嘗試過類似的情況,實際上這不起作用。 我自己還沒有需要的修復版本的hibernate,但是修改允許指定FetchType作爲createAlias的第三個參數,可以這樣做。 請參閱http://opensource.atlassian.com/projects/hibernate/browse/HHH-1696 – 2010-01-30 12:53:39

+0

在我自己的評論 - 我在標準中有重載,但它不是FetchType是第三個參數,它是CriteriaSpecification。雖然我沒有看到它正確的這個問題。 引用的jira是爲了將此重載添加到DetachedCriteria中,這不在此處播放。 – 2010-01-30 13:26:30

0

如果是錯誤I reported a while ago:我通常的解決辦法是隻取匹配項的ID的,然後在後續的查詢選擇其種類的物品:

List<Serializable> ids = session.createCriteria(Item.class) 
    .createAlias("categories","category") 
    .add(Restrictions.eq("category.name",categoryFilter)) 
    .setProjection(Projections.id()) 
    .list(); 

List<Items> items = session.createCriteria(Item.class) 
    .add(Restrictions.in("id", ids) 
    .createAlias("categories","category") 
    .list(); 
0

另一種解決方案是使用Exists子查詢,以便FetchMode.JOIN也可以工作。 (這裏使用的DetachedCriteria但標準應該是相似的)

DetachedCriteria criteria = session.createCriteria(Item.class, "i"); 
criteria.setFetchMode("categories", FetchMode.JOIN); 

DetachedCriteria catCriteria = DetachedCriteria.forClass(Category.class, "category"); 
catCriteria.add(Restrictions.eq("name", categoryFilter)); 
catCriteria.add(Restrictions.eqProperty("category.id", "i.categoryId")); 
criteria.add(Subqueries.exists(catCriteria.setProjection(Projections.property("category.id")))); 

希望這可以幫助其他人也因爲該文檔是如此很難搞清楚。我還添加了一個github gist並附加註釋