Hibernate 圣杯N+;1查询
我的Grails应用程序使用Spring安全性,并具有常见的Hibernate 圣杯N+;1查询,hibernate,grails,gorm,Hibernate,Grails,Gorm,我的Grails应用程序使用Spring安全性,并具有常见的用户、用户角色和角色类。这些类的建模方式并不罕见,因为在用户或角色中都没有具有许多映射。相反,这些类仅通过UserRole引用 class UserRole implements Serializable { User user Role role } 我的理解是,出于性能方面的原因,特别是为了减少N+1查询的可能性,对关系进行了这样的建模 在应用程序的一部分中,我需要加载所有用户及其角色。意识到上述问题,我试着这样做: de
用户
、用户角色
和角色
类。这些类的建模方式并不罕见,因为在用户
或角色
中都没有具有许多
映射。相反,这些类仅通过UserRole
引用
class UserRole implements Serializable {
User user
Role role
}
我的理解是,出于性能方面的原因,特别是为了减少N+1查询的可能性,对关系进行了这样的建模
在应用程序的一部分中,我需要加载所有用户及其角色。意识到上述问题,我试着这样做:
def usersByRole = UserRole.createCriteria().list {
fetchMode("user", FetchMode.JOIN)
fetchMode("role", FetchMode.JOIN)
}
但是,当我尝试访问用户对象时
usersByRole.each { it.user }
发出一个单独的查询来从User
表中检索数据,因此我遇到了我试图避免的问题。我也尝试了以下方法,但它也遇到了同样的问题
def usersByRole = UserRole.createCriteria().list {
fetchMode("user", FetchMode.SELECT)
fetchMode("role", FetchMode.SELECT)
}
我应该承认,我并不完全清楚
FetchMode.JOIN
和FetchMode.SELECT
之间的区别,因此如果有人能告诉我这一点,我将不胜感激。我尝试了几种组合,但得到了相同的结果-如果您查看生成的SQL,原始查询中没有连接,因此,它必须执行额外的查询来加载用户和角色
其他人对此域类有问题-看起来GORM中有一个bug,它包含由域类组成的复合密钥,或者类似的东西。通常,人们对HQL解决方案感到满意,如果运气好,您也会满意:)
def usersByRole = UserRole.executeQuery(
'select ur from UserRole ur ' +
'left join fetch ur.user ' +
'left join fetch ur.role')