【发布时间】:2013-08-25 11:43:22
【问题描述】:
我有下面提到的实体关系。当我运行我的应用程序时,我可以看到 Hibernate 生成的以下查询执行了 13 次(1+12),其中 12 是我在前端应用程序中显示的行数。理想情况下,它应该只执行一次,因为我不确定它为什么会执行 12 次。如果我将要在前端应用程序中显示的行数更改为 20,则查询将执行 21 次。
我该如何解决这个问题?
Hibernate 自动生成的查询
select employee0_.EMPLOYEE_NUMBER as EMP1_2_0_, employee0_.DEPARTMENT_CODE as
DEPARTMENT3_2_0_, employee0_.EMPLOYEE_DEPT as EMPLOYEE4_2_0_, employee0_.DESIGNATION
as DESIGNAT5_2_0_, employee0_.EMPLOYEE_NAME as EMPLOYEE6_2_0_ from EMPLOYEES
employee0_ where employee0_.EMPLOYEE_NUMBER=?
实体类
@Entity
public class Project
@ManyToOne
@JoinColumn(name = "EMPLOYEE_NUMBER", referencedColumnName = "EMPLOYEE_NUMBER")
private Employee requester;
@ManyToOne
@JoinColumn(name = "APPROVER", referencedColumnName = "EMPLOYEE_NUMBER")
private Employee approver;
}
@Entity
public class Employee {
@OneToMany(mappedBy = "requester")
private Set<Project> requestedProjects;
@OneToMany(mappedBy = "approver")
private Set<Project> approvedProjects;
}
JSF UI 源代码
<p:dataTable id="dataTable" var="proj" lazy="true"
value="#{projMB.lazyModel}" styleClass="projTableStyle"
paginator="true" paginatorPosition="bottom" rows="12"
rowKey="#{proj.projectId}">
<f:facet name="header">
<p:column id="employeeNo" headerText="Employee Name" width="16">
<h:outputText value="#{proj.empNumber.employeeName}" />
</p:column>
.....
.....
DAOImpl 类用于检索记录
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Project> c = cb.createQuery(Project.class);
Root<Project> emp = c.from(Project.class);
c.orderBy(cb.desc(emp.get("projectId")));
c.select(emp);
CriteriaQuery<Long> countQ = cb.createQuery(Long.class);
Root<Project> empCount = countQ.from(Project.class);
countQ.select(cb.count(empCount));
List<Predicate> criteria = new ArrayList<Predicate>();
if (projectId != null) {
ParameterExpression<String> pexp = cb.parameter(String.class,
"projectId");
Predicate predicate = cb.equal(emp.get(Project_.projectId), pexp);
criteria.add(predicate);
}
TypedQuery<Project> q = entityManager.createQuery(c);
控制器类
private List<Project> project = new ArrayList<Project>();
project = myservice.getDAOValues();
....
表格显示如下
Employee No, Employee Name, Project Id, Project Start Date
编辑 2
@ManyToOne
@JoinColumn(name = "REQUESTOR", referencedColumnName = "EMPLOYEE_NUMBER",
insertable = false, updatable = false)
private RequesterDepartment requesterDepartment;
【问题讨论】:
-
您在 UI 中显示什么?您如何获取要显示的信息?
-
@JBNizet 我正在使用 JSF Primefaces,并且在我的问题中包含了我的 JSF 代码,如果遗漏了您询问的任何信息,请告诉我。谢谢
-
我不知道 Primefaces。您在控制器中获得的数据是什么,您如何获得它,即您正在执行哪个 JPQL/标准查询?表格显示了什么?
-
如果我没记错的话,你可以避免使用 fetch join 或 fetch subselect 的 n+1 行为:docs.jboss.org/hibernate/core/3.3/reference/en/html/…
-
@JBNizet 我更新了问题,其中包含来自 DAOImpl、控制器类的代码 sn-ps 的详细信息。谢谢