2012-03-07 28 views
15

我正在使用hibernate,並且遇到麻煩創建一個hql查詢來獲取我的對象的所有子項。例如: 對象用戶有汽車列表和朋友列表。如何在Hibernate中離開連接取多個孩子?

要得到一個用戶與他的汽車,我會使用以下查詢:
從用戶u左加入抓取u.cars其中u.id =?

這工作得很好,所以我認爲這將是很容易得到用戶用他的車和他的朋友與以下查詢:從用戶
ü左加入取u.cars LEFT JOIN取u.friends哪裏u.id =?

但是這給了我以下錯誤:
HibernateException的:不能同時獲取多袋

現在我的問題是:什麼是休眠獲取多個孩子的正確方法?

+0

重複:http://stackoverflow.com/questions/4334970/hibernate-cannot-simultaneously-fetch-multiple-bags。用Hibernate使用:@LazyCollection(LazyCollectionOption.FALSE) – willome 2016-08-29 13:40:05

回答

10

至多有一個兒童收藏必須是一個包(即聲明爲一個列表)。將其他集合聲明爲集合,它將起作用。

雖然做這樣的提取連接會產生行的笛卡爾積。如果兩個集合都有100個元素,則這樣的查詢會從數據庫中檢索10,000行。執行第一個查詢獲取一個集合,第二個查詢獲取另一個集合(從而將檢索到的行數減少到200)有時更高效。這也是避免您遇到的問題的一種方法:

select u from User u left join fetch u.cars where u.id = :id; 
select u from User u left join fetch u.friends where u.id = :id; 
+1

很高興知道。不直觀地顯而易見的是,第二查詢實際上將在由第一查詢加載的相同用戶實體上填充好友集合。但這就是它的工作原理(感謝緩存)! – 2013-01-15 09:09:18

+1

這兩個HSQL查詢可以寫入一個'@ NamedQuery'嗎? – MyTitle 2013-11-07 11:14:47

+0

@MyTitle:no。命名查詢是單個查詢,而不是兩個。 – 2013-11-07 14:22:50

6

您剛剛點擊Collection/List(bag)問題。

這是一個Hibernate官方「問題」的鏈接:https://hibernate.atlassian.net/browse/HHH-1718。正如你所看到的,它已於2006年開放,並且仍然開放。除了JB Nizet提出的建議之外,我建議你在你的模型中使用Set而不是Collection或List(否則),否則,你也可以將Collection/List指定爲FetchMode.SUBSELECT並作爲最後一個選項(很難實現),你可以在@ OneToMany/@ ManyToMany上使用@IndexColumn。

這篇博客文章將引導你進入實施解決方案:http://jroller.com/eyallupu/entry/hibernate_exception_simultaneously_fetch_multiple

換句話說,有沒有解決方案,做的正是你想做的事,但解決方法是什麼。

希望這會有所幫助!

編輯:錯字

0

不可能的,因爲這將是應用/數據庫太重, 您需要分別創建2個獨立的標準和檢索數據。

Cat cat = sess.createCriteria(Cat.class) 
       .add(Restrictions.like("name", "F%")) 
       .uniqueResult(); 

List kitten = sess.createCriteria(Kitten.class) 
        .add(Restrictions.eq("cat", cat)) 
        .createCriteria("kittens") 
        .add(Restrictions.like("name", "F%")) 
        .list(); 

List mate = sess.createCriteria(Mate.class) 
       .add(Restrictions.eq("cat", cat)) 
       .createCriteria("mate") 
       .add(Restrictions.like("name", "F%")) 
       .list(); 
相關問題