如果有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,甚至设置了渴望。但他们都没有工作。
答案 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 的每个实例。而你是对的 - 创建列表时不需要它。也许你之后有一些迭代调用刷新(可能是为了将实例附加到会话)?