hibernate标准执行额外的查询

时间:2015-10-28 08:47:20

标签: java hibernate postgresql criteria

如果有N名员工,则执行N + 1次查询。我希望它只执行一次查询。

@Entity
public class Employee {

 @Id
 private int employeeId;

 private String employeeName;

 private Department department;

 private List<Dependents> dependents;

 //getter setter for employeeId and employeeName

 @ManyToOne
 @JoinColumn(name = "id_department")
 public Department getDepartment() {
    return department;
 }

 public void setDepartment(Department department) {
    this.department = department;
 }

 @OneToMany(mappedBy = "employee", cascade = CascadeType.ALL)
 public List<Dependents> getDependents() {
    return dependents;
 }

 public void setDependents(List<Dependents> dependents) {
    this.dependents = dependents;
 }

}

@Entity
public class Department {

 @Id
 private int departmentId;

 private String departmentName;

 //Getter setters
}

@Entity
public class Dependents {

 @Id
 private int dependentsId;

 private String dependentsName;

 private Employee employee;

 //Getter setters for dependentsId and dependentsName

 @ManyToOne
 @JoinColumn(name = "id_employee")
 public Employee getEmployee() {
    return employee;
 }

 public void setEmployee(Employee employee) {
    this.employee = employee;
 }
}

我正在使用结果标准

Criteria criteria=session.createCriteria(Employee.class);
criteria.createAlias("department","department");
criteria.createAlias("dependents","dependents");
criteria.add(Restrictions.eq("department.departmentId",depId);
return criteria.list();

结果是N + 1个查询。第一个查询检索所有员工,然后为每个员工查询一个查询以检索其详细信息,即使第一个查询已返回所有必需信息。

//First Query
select this_.id_employee as id_empl1_7_5_,
    this_.id_department as id_depart11_7_5_,
    this_.employee_name as tx_name3_7_5_,
    department1_.id_department as id_depart1_30_0_,
    department1_.department_name as tx_departm2_30_0_,
    dependent1_.id_dependent as id_depen1_6_2_,
    dependent1_.dependent_name as tx_depend2_6_2_,
    dependent1_.id_employee as id_employ3_6_2_,
from
    employee_details this_ 
inner join
    department department1_ 
        on this_.id_department=department1_.id_department 
inner join
    dependents dependent1_ 
        on this_.id_employee=dependent1_.id_employee 
where
    department1_.id_department=? 

对于每位员工,它会触发一个查询:

select
    employe0_.id_employee as id_empl1_7_0_,
    employe0_.id_department as id_depa11_7_0_,
    employe0_.emloyee_name as emloye2_7_0_,
    department1_.id_department as id_depar1_30_1_,
    department1_.department_name as depar2_30_1_,
    dependent1_.id_department as nu_seque1_6_2_,
    dependent1_.department_name as is_curre2_6_2_,
    dependent1_.id_employee as id_empl2_6_2_,
from
    employee_details employe0_ 
left outer join
    department department1_ 
        on employe0_.id_department=department1_.id_department 
left outer join
    dependents dependent1_ 
        on this_.id_employee=dependent1_.id_employee 
where
    employe0_.id_employee=?

我已经尝试过FetchMode.Join,Custom ResultTransformer,甚至设置了渴望。但他们都没有工作。

2 个答案:

答案 0 :(得分:0)

你试过吗

Criteria criteria = session.createCriteria(Employee.class);
criteria.setFetchMode("department", FetchMode.EAGER);
criteria.setFetchMode("dependents", FetchMode.EAGER);
criteria.add(Restrictions.eq("department.departmentId",depId));

或Hql:

session.createQuery("from Employee emp join fetch emp.department dept join fetch emp.dependents depnd where dept.departmentId = :deptid").setParameter("deptid",depId).list();

答案 1 :(得分:0)

很抱歉这个问题很难见但是你确定这两个SQL是在criteria.list();调用期间准确生成的吗? 因为似乎Hibernate试图刷新 Employee 的每个实例。而你是对的 - 创建列表时不需要它。也许你之后有一些迭代调用刷新(可能是为了将实例附加到会话)?