2015-02-11 26 views
1

我试图在Hibernate中使用FetchMode.JOIN来理解但是面临某些问题。 我有3类Department,Employee和EmployeeMain类。部门与员工有一对多的关系。休眠获取模式加入不工作

下面是代码 系类: -

@Entity 
@Table(name="DEPARTMENT") 
public class Department { 

@Id 
@GeneratedValue 
@Column(name="DEPARTMENT_ID") 
private Long departmentId; 

@Column(name="DEPT_NAME") 
private String departmentName; 

@OneToMany(mappedBy="department") 
@Fetch(FetchMode.JOIN) 
private List<Employee> employees = new ArrayList<>(); 

public Long getDepartmentId() { 
    return departmentId; 
} 

public void setDepartmentId(Long departmentId) { 
    this.departmentId = departmentId; 
} 

public String getDepartmentName() { 
    return departmentName; 
} 

public void setDepartmentName(String departmentName) { 
    this.departmentName = departmentName; 
} 

public List<Employee> getEmployees() { 
    return employees; 
} 

public void setEmployees(List<Employee> employees) { 
    this.employees = employees; 
} 

} 

Employee类: -

@Entity 
@Table(name="EMPLOYEE") 
public class Employee { 
@Id 
@GeneratedValue 
@Column(name="employee_id") 
private Long employeeId; 

@Column(name="firstname") 
private String firstname; 

@Column(name="lastname") 
private String lastname; 

@Column(name="birth_date") 
private Date birthDate; 

@Column(name="cell_phone") 
private String cellphone; 

@ManyToOne 
@JoinColumn(name="department_id") 
private Department department; 

public Employee() { 

    } 

    public Department getDepartment() { 
    return department; 
} 

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

    public Employee(String firstname, String lastname, String phone) { 
     this.firstname = firstname; 
     this.lastname = lastname; 
     this.birthDate = new Date(System.currentTimeMillis()); 
     this.cellphone = phone; 
    } 


public Long getEmployeeId() { 
    return employeeId; 
} 

public void setEmployeeId(Long employeeId) { 
    this.employeeId = employeeId; 
} 

public String getFirstname() { 
    return firstname; 
} 

public void setFirstname(String firstname) { 
    this.firstname = firstname; 
} 

public String getLastname() { 
    return lastname; 
} 

public void setLastname(String lastname) { 
    this.lastname = lastname; 
} 

public Date getBirthDate() { 
    return birthDate; 
} 

public void setBirthDate(Date birthDate) { 
    this.birthDate = birthDate; 
} 

public String getCellphone() { 
    return cellphone; 
} 

public void setCellphone(String cellphone) { 
    this.cellphone = cellphone; 
} 

}

主要类别: -

public class EmployeeMain { 
public static void main(String[] args) { 
    SessionFactory sessionFactory = new  Configuration().configure("hibernate.xml").buildSessionFactory(); 
    Session session = sessionFactory.openSession(); 
    session.beginTransaction(); 
    Department department1 = new Department(); 
    department1.setDepartmentName("Sales"); 
    session.save(department1); 
    Department department2 = new Department(); 
    department2.setDepartmentName("Operations"); 
    session.save(department2); 


    Employee emp1 = new Employee("Nina", "Mayers", "111"); 
    Employee emp2 = new Employee("Tony", "Almeida", "222"); 

    Employee emp3 = new Employee("Rina", "Coyeet", "333"); 
    Employee emp4 = new Employee("Mary", "Land", "444"); 

    emp1.setDepartment(department1); 
    emp2.setDepartment(department1); 

    emp3.setDepartment(department2); 
    emp4.setDepartment(department2); 

    department1.setEmployees(new ArrayList<Employee>()); 
    department1.getEmployees().add(emp1); 
    department1.getEmployees().add(emp2); 

    department2.getEmployees().add(emp3); 
    department2.getEmployees().add(emp4); 

    session.save(emp1); 
    session.save(emp2); 

    session.save(emp3); 
    session.save(emp4); 
    session.getTransaction().commit(); 
    session.close(); 

    session = sessionFactory.openSession(); 
    session.beginTransaction(); 

    List<Department> departmentList = session.createQuery("from Department").list(); 
    for(Department department : departmentList){ 
     department.getEmployees(); 
    } 

} 

} 

我有各部门下设2个部门和2名员工。 尽管在Department类中我提到了@Fetch(FetchMode.JOIN)for employees对象,但Employees的查询为每个部门运行两次。基本上,如果我正确地提到的是N + 1选择问题。但根据我的观点,如果FetchMode是Join,那么一个查询就会被解雇并加入Employee和Department,并且应该已经获取了数据。 但是下面的查询被解雇了。 查询1

Hibernate: select department0_.DEPARTMENT_ID as DEPARTME1_0_, department0_.DEPT_NAME as DEPT_NAM2_0_ from DEPARTMENT department0_ 

查询2

Hibernate: select employees0_.department_id as departme6_0_0_, employees0_.employee_id as employee1_1_0_, employees0_.employee_id as employee1_1_1_, employees0_.birth_date as birth_da2_1_1_, employees0_.cell_phone as cell_pho3_1_1_, employees0_.department_id as departme6_1_1_, employees0_.firstname as firstnam4_1_1_, employees0_.lastname as lastname5_1_1_ from EMPLOYEE employees0_ where employees0_.department_id=? 

查询3

Hibernate: select employees0_.department_id as departme6_0_0_, employees0_.employee_id as employee1_1_0_, employees0_.employee_id as employee1_1_1_, employees0_.birth_date as birth_da2_1_1_, employees0_.cell_phone as cell_pho3_1_1_, employees0_.department_id as departme6_1_1_, employees0_.firstname as firstnam4_1_1_, employees0_.lastname as lastname5_1_1_ from EMPLOYEE employees0_ where employees0_.department_id=? 

回答

5

HQL查询不取基于注释关联。要实现此目标,您必须在HQL查询中指定获取策略:

from Department d inner join fetch d.employees