2013-05-13 102 views
4

我的Grails應用程序使用Spring Security並具有通常的User,UserRoleRole類。這些類的建模方式很少見,因爲UserRole中沒有hasMany映射。相反,這些類僅通過UserRole引用。Grails N + 1查詢

class UserRole implements Serializable { 
    User user 
    Role role 
} 

我的理解是,該關係已被建模這樣出於性能原因,具體地,以減小N + 1次的查詢的可能性。

在我的應用程序的一部分中,我需要加載所有用戶及其角色。意識到上述問題的,我試圖做這樣的:

def usersByRole = UserRole.createCriteria().list { 
    fetchMode("user", FetchMode.JOIN) 
    fetchMode("role", FetchMode.JOIN) 
} 

然而,當我嘗試訪問User objects

usersByRole.each { it.user } 

一個單獨的查詢被頒發給來自User表中檢索數據,所以我遇到了我試圖避免的問題。我也試過以下,但它遭受同樣的問題。

def usersByRole = UserRole.createCriteria().list { 
    fetchMode("user", FetchMode.SELECT) 
    fetchMode("role", FetchMode.SELECT) 
} 

我應該承認,我不是FetchMode.JOINFetchMode.SELECT之間的差別完全清楚,因此,如果任何人都可以把我直上,它會受到讚賞。

回答

6

我嘗試了幾種組合,但有相同的結果 - 如果你看一下生成的SQL有一個在原始查詢沒有連接,所以必須做額外查詢加載用戶和角色。

其他人有這個域類的問題 - 它看起來像GORM中有一個錯誤,其中有一個由域類組成的組合鍵或類似的東西。通常人們對HQL解決方案感到滿意,並且運氣好的話你也會這樣:)

def usersByRole = UserRole.executeQuery(
    'select ur from UserRole ur ' + 
    'left join fetch ur.user ' + 
    'left join fetch ur.role')