Grails 2.4.4完全忽略了fetch:' join' *使用PostgreSQL时*

时间:2015-03-17 15:21:24

标签: hibernate postgresql grails groovy gorm

更新:这似乎只在使用PostgreSQL时发生。我在这里提交了一个项目:https://github.com/jbwiv/testfetch有两个分支。 "主"使用h2和" postgres"使用PostgreSQL。

尝试每个分支,然后转到localhost:8080 / testfetch / console。

在该控制台中,键入:

import testfetch.Employee
import testfetch.User
Employee.list()

在H2,我得到了我的期望:

hibernate.SQL select this_.id as id1_1_1_, this_.version as version2_1_1_, user2_.id as id1_0_0_, user2_.version as version2_0_0_, user2_.employee_id as employee3_0_0_ from employee this_ left outer join app_user user2_ on this_.id=user2_.employee_id

然而,在postgres分支中,我得到:

hibernate.SQL /* criteria query */ select this_.id as id1_1_0_, this_.version as version2_1_0_ from employee this_
hibernate.SQL /* load testfetch.User */ select user0_.id as id1_0_0_, user0_.version as version2_0_0_, user0_.employee_id as employee3_0_0_ from app_user user0_ where user0_.employee_id=?
hibernate.SQL /* load testfetch.User */ select user0_.id as id1_0_0_, user0_.version as version2_0_0_, user0_.employee_id as employee3_0_0_ from app_user user0_ where user0_.employee_id=?
hibernate.SQL /* load testfetch.User */ select user0_.id as id1_0_0_, user0_.version as version2_0_0_, user0_.employee_id as employee3_0_0_ from app_user user0_ where user0_.employee_id=?
hibernate.SQL /* load testfetch.User */ select user0_.id as id1_0_0_, user0_.version as version2_0_0_, user0_.employee_id as employee3_0_0_ from app_user user0_ where user0_.employee_id=?
hibernate.SQL /* load testfetch.User */ select user0_.id as id1_0_0_, user0_.version as version2_0_0_, user0_.employee_id as employee3_0_0_ from app_user user0_ where user0_.employee_id=?
hibernate.SQL /* load testfetch.User */ select user0_.id as id1_0_0_, user0_.version as version2_0_0_, user0_.employee_id as employee3_0_0_ from app_user user0_ where user0_.employee_id=?
hibernate.SQL /* load testfetch.User */ select user0_.id as id1_0_0_, user0_.version as version2_0_0_, user0_.employee_id as employee3_0_0_ from app_user user0_ where user0_.employee_id=?
hibernate.SQL /* load testfetch.User */ select user0_.id as id1_0_0_, user0_.version as version2_0_0_, user0_.employee_id as employee3_0_0_ from app_user user0_ where user0_.employee_id=?
hibernate.SQL /* load testfetch.User */ select user0_.id as id1_0_0_, user0_.version as version2_0_0_, user0_.employee_id as employee3_0_0_ from app_user user0_ where user0_.employee_id=?
hibernate.SQL /* load testfetch.User */ select user0_.id as id1_0_0_, user0_.version as version2_0_0_, user0_.employee_id as employee3_0_0_ from app_user user0_ where user0_.employee_id=?
hibernate.SQL /* load testfetch.User */ select user0_.id as id1_0_0_, user0_.version as version2_0_0_, user0_.employee_id as employee3_0_0_ from app_user user0_ where user0_.employee_id=?
hibernate.SQL /* load testfetch.User */ select user0_.id as id1_0_0_, user0_.version as version2_0_0_, user0_.employee_id as employee3_0_0_ from app_user user0_ where user0_.employee_id=?
hibernate.SQL /* load testfetch.User */ select user0_.id as id1_0_0_, user0_.version as version2_0_0_, user0_.employee_id as employee3_0_0_ from app_user user0_ where user0_.employee_id=?
hibernate.SQL /* load testfetch.User */ select user0_.id as id1_0_0_, user0_.version as version2_0_0_, user0_.employee_id as employee3_0_0_ from app_user user0_ where user0_.employee_id=?
hibernate.SQL /* load testfetch.User */ select user0_.id as id1_0_0_, user0_.version as version2_0_0_, user0_.employee_id as employee3_0_0_ from app_user user0_ where user0_.employee_id=?
hibernate.SQL /* load testfetch.User */ select user0_.id as id1_0_0_, user0_.version as version2_0_0_, user0_.employee_id as employee3_0_0_ from app_user user0_ where user0_.employee_id=?
hibernate.SQL /* load testfetch.User */ select user0_.id as id1_0_0_, user0_.version as version2_0_0_, user0_.employee_id as employee3_0_0_ from app_user user0_ where user0_.employee_id=?
hibernate.SQL /* load testfetch.User */ select user0_.id as id1_0_0_, user0_.version as version2_0_0_, user0_.employee_id as employee3_0_0_ from app_user user0_ where user0_.employee_id=?
hibernate.SQL /* load testfetch.User */ select user0_.id as id1_0_0_, user0_.version as version2_0_0_, user0_.employee_id as employee3_0_0_ from app_user user0_ where user0_.employee_id=?
hibernate.SQL /* load testfetch.User */ select user0_.id as id1_0_0_, user0_.version as version2_0_0_, user0_.employee_id as employee3_0_0_ from app_user user0_ where user0_.employee_id=?

这对我们来说是一个巨大的阻碍。我非常感谢您提供的任何反馈。

我正在实时使用Hibernate4在Grails 2.4.4中正常工作。

例如,我有两个类,Employee和User。

class Employee {
  User user
  static mapping = {
    user fetch:'join'
  }
  static belongsTo = User    
}

class User {
  Employee employee 
  static mapping = {
    employee fetch:'join'
    table 'app_user'
  }
}

但是,当我尝试使用此设置查询这些对象时,我仍然最终出现N + 1问题。例如

Employee.list()
Employee.executeQuery("select e from Employee e")

所有这些导致对Employee表的一次查询,该表返回21名员工,然后对app_user表(用户映射到的)进行21次查询。

然而,

Employee.withCriteria {fetchMode 'user', FetchMode.JOIN)

的工作原理。在这种情况下,我只执行了一个查询。

我做错了什么?

蒂亚。

1 个答案:

答案 0 :(得分:0)

zyro在JIRA问题中正确地指出我们的PostgreSQL配置中有“max_fetch_depth = 0”。

引用他:

postgres分支有dataSource.hibernate.max_fetch_depth = 0,而hibernate docs说A 0禁用默认的外连接提取。这可能是原因吗?

确实,在删除它之后,它以预期的方式执行。