hibernate - Grails 2.4.4 完全忽略提取 :'join' *使用 PostgreSQL 时*

标签 hibernate postgresql grails groovy grails-orm

更新:这似乎只发生在使用 PostgreSQL 时。我在这里提交了一个项目:https://github.com/jbwiv/testfetch有两个分支。 “master”使用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=?

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

我在 Grails 2.4.4 和 Hibernate4 中实时获得惰性行为以正常工作。

例如,我有两个类,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 表(User 映射到该表)进行 21 次查询。

但是,

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

有效。在这种情况下,我只执行了一个查询。

我做错了什么?

蒂亚。

最佳答案

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

引用他的话:

postgres 分支有 dataSource.hibernate.max_fetch_depth = 0 并且 hibernate 文档说 A 0 禁用默认外部连接提取。这可能是原因吗?

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

关于hibernate - Grails 2.4.4 完全忽略提取 :'join' *使用 PostgreSQL 时*,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29102963/

相关文章:

java - Hibernate Session Factory 需要很长时间才能加载

django - 从查询集中的 jsonfield 中选择值

ajax - Grails 中的 jQuery Ajax 请求

email - Groovy电子邮件客户端可在Exchange 2003和Exchange 2010上使用

java - 关于 Spring @Autowired 和 Spring JDBC 的问题

java - Hibernate二级缓存只写不读

sql - 如何在不使用 Postgres 中的 UPDATE 查询的情况下更新记录

unit-testing - 可以在 Controller 的show()方法中使用模拟域 “instance”吗?

java - Spring-Roo JPA 创建的实体未更新

node.js - Postgres 的序列化和对等身份验证?