2015-10-28 2 views
1

S'il y a N employés, il exécute les requêtes N + 1. Je veux qu'il n'exécute qu'une seule requête.Critères d'hibernation exécution de requêtes supplémentaires

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

J'UTILISE Critères pour Résultat

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

Il Résultats dans les requêtes N + 1. 1ère requête pour récupérer tous les employés et ensuite pour chaque employé une requête pour récupérer ses détails même si la première requête avait renvoyé toutes les informations requises.

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

Et pour chaque employé-il se déclenche une requête:

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

J'ai déjà essayé FetchMode.JOIN, personnalisé ResultTransformer et même la mise en l'empressement. Mais aucun d'eux n'a travaillé.

+0

Avez-vous trouvé la solution, Si oui veuillez me le dire parce que je suis également bloqué sur ce problème? – Sahil

Répondre

0

Avez-vous essayé

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

Ou hQPD:

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

Désolé pour être Nurdy mais êtes-vous sûr que ces deux requêtes SQL sont produits exactement au cours criteria.list(); appel? Parce qu'il semble que Hibernate essaie d'actualiser chaque instance de Employé. Et vous avez raison - ce n'est pas nécessaire lorsque la liste est créée. Peut-être que vous avez une certaine itération par la suite où l'actualisation est appelée (peut-être afin de joindre une instance à la session)?