简体   繁体   中英

hibernate criteria executing extra queries

If there are N employees it executes the N+1 queries. I want it to execute only 1 query.

@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;
 }
}

I am Using Criteria for Result

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

It Results in N+1 queries. 1st query to retrieve all employees and then for each employee one query to retrieve its details even though first query had return all the required information.

//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=? 

And for-each employee it fire one query:

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=?

I have already tried FetchMode.Join, Custom ResultTransformer and even setting the eagerness. But none of them worked.

Have you tried

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

Or Hql :

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

Sorry for being nurdy but are you sure that these two SQLs are produced exactly during criteria.list(); call? Because it seems that Hibernate tries to refresh each instance of Employee . And you are right - it is not needed when list is created. Maybe you have some iteration afterwards where refresh is called (maybe in order to attach instance to the session)?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM