我正在使用 Spring Boot 实现基本的员工管理 CRUD API。 以下是我希望您关注的实体和服务。
我正在尝试创建这种双向关系:
An employee belongs to a single department, a department has many employees
员工/Employee.java
@Entity
@Table(name = "employee")
public class Employee {
...
@ManyToOne
@JoinColumn(name = "department_id")
@JsonIgnoreProperties("employees")
private Department department;
...
}
部门/部门.java
@Entity
@Table(name = "department")
public class Department {
...
@OneToMany(mappedBy = "department", targetEntity = Employee.class, cascade = CascadeType.PERSIST)
@JsonIgnoreProperties("department")
private Set<Employee> employees;
...
}
部门/DepartmentService.java
...
public Employee addEmployeeToDepartment(UUID id, UUID empId) {
Employee emp = employeeRepository.findById(empId).orElseThrow(EmployeeNotFoundException::new);
Department dept = departmentRepository.findById(id).orElseThrow(DepartmentNotFoundException::new);
emp.setDepartment(dept);
return employeeRepository.save(emp);
}
...
我的问题:
当我尝试将员工添加到新部门时,会运行以下查询:
Hibernate: select e1_0.id,e1_0.address,e1_0.date_of_join,d1_0.id,d1_0.name,e1_0.email,e1_0.first_name,e1_0.last_name,e1_0.phone_number from employee e1_0 left join department d1_0 on d1_0.id=e1_0.department_id where e1_0.id=?
Hibernate: select d1_0.id,d1_0.name from department d1_0 where d1_0.id=?
Hibernate: update employee set address=?,date_of_join=?,department_id=?,email=?,first_name=?,last_name=?,phone_number=? where id=?
但是当我尝试将员工添加到该员工当前所在的同一部门时,会运行以下查询:
Hibernate: select e1_0.id,e1_0.address,e1_0.date_of_join,d1_0.id,d1_0.name,e1_0.email,e1_0.first_name,e1_0.last_name,e1_0.phone_number from employee e1_0 left join department d1_0 on d1_0.id=e1_0.department_id where e1_0.id=?
你能解释一下这是怎么发生的吗? 如果需要的话,也许可以向我指出相关的休眠文档。
我预计每次都会运行 3 个查询:
fetch employee
fetch department
update employee
正如我在服务中所写的那样。但从日志来看似乎并非如此。
在您的
Employee
实体中,注释为 department
的 @ManyToOne
字段默认会立即获取。这就是为什么当您尝试获取 Employee
时会看到 join 子句。
在您的 Department
实体中,您有 @OneToMany
,默认情况下,其获取类型为惰性,因此没有连接,只有普通的旧选择位置,没有其他表中的任何其他内容。