2

我有下面提到的实体关系。当我运行我的应用程序时,我可以看到 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 用户界面源

<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;
4

1 回答 1

1

您希望在单个查询中加载项目及其各自的请求者或批准者。这是使用 fetch join 完成的。在 JPQL 中:

select p from Project p
left join fetch p.requester
where ...

在 Criteria 中,有一个等效的构造:

Root<Project> project = c.from(Project.class);
project.fetch(Project_.requester, JoinType.LEFT);

请注意,我重命名empproject:emp将是几乎可以接受的 Employee 路径名称。将它用于Project路径是非常令人困惑的。

于 2013-08-26T07:47:45.110 回答