我有两个实体Employee.class
和Project.class
,它们之间有@ManyToMany
个关系。
当我尝试更新Employee
并通过JSP表单向其添加另一个Project
时,控制器会使Set<Project>
为空。因此,当我提交表单时,休眠而不是向Set<Project>
添加另一个项目,这样做:
Hibernate: update employee set ....(IT'S OK)
Hibernate: update project set...(IT'S OK)
Hibernate: delete from employee_project where employee_id=?(IT'S NOT OK)
Employee.class
@Entity
@Table(name="employee")
public class Employee{
//other fields
@ManyToMany(fetch= FetchType.EAGER,
cascade=CascadeType.ALL)
@JoinTable(name="employee_project",joinColumns=@JoinColumn(name="employee_id"),
inverseJoinColumns=@JoinColumn(name="project_id"))
private Set<Project> projects = new HashSet<>();
public Set<Project> getProjects() {
return projects;
}
public void setProjects(Set<Project> projects) {
this.projects = projects;
}
Project.class
@Entity
@Table(name="project")
public class Project {
@ManyToMany(fetch= FetchType.EAGER, mappedBy="projects")
private Set<Employee> employees = new HashSet<>();
public Set<Employee> getEmployees() {
return employees;
}
public void setEmployees(Set<Employee> employees) {
this.employees = employees;
}
EmployeeController.class
@GetMapping("/employeeForm")
public String showEmployeeForm(Model theModel) {
Employee theEmployee = new Employee();
theModel.addAttribute("employee", theEmployee);
theModel.addAttribute("projects", projectService.getProjectsIdMap());
return "employee-form";
}
@GetMapping("/employee/{id}/updateEmployee")
public String updateEmployee(@PathVariable("id") Long employeeId, Model theModel) {
//HERE MY Set<Project> IS FULL OF PROJECTS
theModel.addAttribute("employee", employeeService.getEmployee(employeeId));
theModel.addAttribute("projects", projectService.getProjectsIdMap());
return "employee-form";
}
@PostMapping("/saveEmployee")
public String saveOrUpdateEmployee(@ModelAttribute("employee")
Employee theEmployee) {
//HERE MY Set<Project> IS EMPTY
theEmployee.getProjects()
.add(projectService
.getProject(theEmployee.getProjectId()));
employeeService.saveEmployee(theEmployee);
return "redirect:/employees/employee/" + theEmployee.getId();
}
雇员-form.jsp
<form:form action="/employee_manager/employees/saveEmployee"
modelAttribute="employee" method="POST">
<form:hidden path="id"/>
<form:select path="projectId">
<form:options items="${projects}" />
</form:select>
<input type="submit" value="Save" />
</div>
</form:form>
Employee.Repository(DAO)
public void saveEmployee(Employee employee) {
Session session = sessionFactory.getCurrentSession();
session.saveOrUpdate(employee);
}
Employee.Service
@Transactional
public void saveEmployee(Employee employee) {
employeeRepository.saveEmployee(employee);
}
数据库结构: enter image description here
看起来某处spring设置了一个新集合,而不是添加到现有集合中。
我正在尝试调试应用流程并按照Set<Projects>
进行操作,我知道此集合会使saveOrUpdateEmployee
方法中的所有值都失效。我无法弄清楚我在哪里弄错了。谢谢你的帮助。
答案 0 :(得分:0)
我找到了可能导致问题的原因。当我提交更新表单时,Spring会创建我的Employee.class
的新实例,这意味着Set<Project>
成为新的空集。由于我传递了员工的<form:hidden path="id">
id,因此hibernate会覆盖数据库中的所有值,包括我的项目集合。
现在我想知道如何防止这种行为?
<form:hidden path="projects">
无效。
使用@InitBinder
- &gt; binder.setDisallowedFields({"projects"})
也不起作用。