关于Hibernate查询的一组问题

时间:2012-02-17 16:06:46

标签: java hibernate hql criteria

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

考虑以下结构:

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

0)HQL中有两种可能的动态提取方式:

  • 从Manager m join m.projects
  • 中选择m
  • 来自Manager m join fetch m.projects

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

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

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

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

1 个答案:

答案 0 :(得分:3)

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个老板(例如)。在参考文档中搜索“批量提取”。

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

3)否.HQL查询参数最终是预处理语句参数。您必须使用字符串连接来执行此操作。