I was trying to use FetchMode.JOIN in Hibernate to understand but facing certain issues . I have 3 classes Department , Employee and EmployeeMain Class. Department has oneToMany relation with Employee .
Below is the code Department Class :-
@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 class :-
@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; } }
Main Class :-
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(); } } } I have inserted 2 departments and 2 Employees under each department . Even though in the Department class I have mentioned @Fetch(FetchMode.JOIN) for employees object still the query for Employees is run twice once for each department . That is basically if I mentioned correctly is the N+1 select problem . But according to me if the FetchMode is Join then a single query would have been fired joining Employee and department and should have fetched the data . But the following queries were fired . Query 1
Hibernate: select department0_.DEPARTMENT_ID as DEPARTME1_0_, department0_.DEPT_NAME as DEPT_NAM2_0_ from DEPARTMENT department0_ Query 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=? Query 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=?