Hibernate 圣杯N+;1查询

Hibernate 圣杯N+;1查询,hibernate,grails,gorm,Hibernate,Grails,Gorm,我的Grails应用程序使用Spring安全性,并具有常见的用户、用户角色和角色类。这些类的建模方式并不罕见,因为在用户或角色中都没有具有许多映射。相反,这些类仅通过UserRole引用 class UserRole implements Serializable { User user Role role } 我的理解是,出于性能方面的原因,特别是为了减少N+1查询的可能性,对关系进行了这样的建模 在应用程序的一部分中,我需要加载所有用户及其角色。意识到上述问题,我试着这样做: de

我的Grails应用程序使用Spring安全性,并具有常见的
用户
用户角色
角色
类。这些类的建模方式并不罕见,因为在
用户
角色
中都没有
具有许多
映射。相反,这些类仅通过
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')