JPA:如何在不加载延迟加载集的情况下计算子记录

时间:2012-07-27 06:10:09

标签: java spring java-ee jpa jpa-2.0

我正在编写J2EE / JPA / Spring 3应用程序,试图保持纯粹的JPA 2.0。我想得到一些子对象,而不必加载它们,因为它显然是一个昂贵的操作。例如,这是一个简化的例子

Organisation
 - OrgID
 - OrgName

Employee
 - EmployeeID
 - OrgID (key to Organisation table)
 - EmployeeName

在jsp页面上,我想显示所有组织的列表以及不加载员工本身的员工数量。如果它可以是单个数据库命中加载所有组织对象,并以某种方式加载一个很好的Employee对象的计数。我宁愿避免一个查询列出组织,然后为每个组织列出一个计算员工的计数。我想我可以添加一个瞬态属性来保持计数,我不知道如何最好地做到这一点。

只是为了了解规模,将有大约50个组织,每个组织将有0到500名员工。我宁愿避免任何特定于实现的扩展,因为我已经更改了一次JPA提供程序,并且可能会再次更改。

在SQL中我只是做一个连接,组和计数,但我不知道如何在JPA中做到这一点。任何帮助表示赞赏!

2 个答案:

答案 0 :(得分:4)

您可以直接选择您定义的对象作为保存组织和计数的结果。然后你只需编写查询。唯一的诀窍是您必须按组织的每个字段手动分组。 'GROUP BY ORGANIZATION'不合法。

public class OrgWithEmpCount {
  private Organisation org;
  private Long empCount;
  public OrgWithEmpCount(Organisation org, Long empCount) {
    this.org = org;
    this.empCount = empCount;
  }
}


Select new full.package.OrgWithEmpCount(o, count(e.employeeId)) 
from Organisation o, IN(o.employees) e 
group by o.orgId, o.orgName, o.whateverElse

答案 1 :(得分:2)

离开Affe接受的答案 - 除了你想要为公司计算甚至没有雇员的情况之外,这种方法很有效。 IN查询最终会排除这些公司。很难想象一个公司零雇员,但为了查询示例,你可以这样做:

select new full.package.OrgWithEmpCount(o, count(e.employeeId))
FROM Organisation o LEFT JOIN e.employees AS e
group by o.orgId, o.orgName, o.whateverElse

你明白了......而不是做IN,做一个LEFT JOIN。