简体   繁体   中英

Hibernate Fetch Mode Join Not working

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

HQL queries do not fetch associations based on annotations. To achieve this goal you have do specify the fetch strategy in the HQL query:

from Department d inner join fetch d.employees

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