【问题标题】:A set of questions on Hibernate quering关于Hibernate查询的一组问题
【发布时间】:2012-02-17 16:06:45
【问题描述】:

请帮助我解决这些 Hibernate 查询问题。

考虑以下结构:

@Entity
class Manager {
    @OneToMany
    List<Project> projects;
}

0) 在 HQL 中有 2 种可能的动态获取方式:

  • select m from Manager m join m.projects
  • 从经理 m 加入 fetch m.projects

在我的设置中,第二个总是返回列表中对象数量错误的笛卡尔积的结果,而第一个总是返回列表中正确数量的实体。但是 sql 查询看起来是一样的。这是否意味着“select”子句会从内存列表中删除冗余对象?在这种情况下,在书中看到使用 select distinct ... 删除冗余实体​​的建议很奇怪,而“select”可以完成这项工作。如果这是一个错误的假设,那么为什么这两个查询会返回不同的结果?

  1. 如果我通过上述 2 种方法之一使用动态提取,我会在我的休眠 SQL 日志中看到经典的 n+1 选择问题输出。实际上,FetchMode 注释(子选择或连接)在动态获取时没有能力。在这种特殊情况下,我真的无法解决 n+1 问题吗?

  2. 看起来 Hibernate Criteria API 不支持泛型。我对吗?看来我必须改用 JPA Criteria API?

  3. 是否可以编写带有实体名称参数的 HQL 查询?例如 "from :myEntityParam p where p.id=1" 并在此之后调用 setParameter("myEntityParam", MyClass.class)。实际上我想要的是通用 HQL 查询,用一个通用的替换多个非通用 dao。

【问题讨论】:

    标签: java hibernate hql criteria


    【解决方案1】:

    0) 我总是使用 select 子句,因为它允许告诉您要选择什么,并且无论如何在 JPQL 中都是强制性的。如果您想选择经理及其项目,请使用

    select distinct m from Manager m left join fetch m.projects
    

    如果不使用 distinct 关键字,列表将包含每个经理的 n 个实例(n 是经理的项目数):Hibernate 返回与结果集中的行数一样多的元素。

    1) 如果要避免 n+1 问题,请在同一查询中获取其他关联:

    select distinct m from Manager m 
    left join fetch m.projects 
    left join fetch m.boss
    

    您还可以配置批量获取以在访问第一个 Boss 时一次加载 10 个 Boss(例如)。在参考文档中搜索“batch fetching”。

    2) 整个 Hibernate API 没有被通用化。它是在泛型之前的 JDK 1.4 上制作的。这并不意味着它没有用。

    3) 否。HQL 查询参数最终是准备好的语句参数。您必须使用字符串连接来执行此操作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-03-20
      • 2013-05-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-26
      • 2011-03-17
      • 1970-01-01
      相关资源
      最近更新 更多