繁体   English   中英

Spring 数据 JPA 实现一对一关系

[英]Spring Data JPA Implementation one to one relationship

我正在尝试实现 Spring 数据 JPA 一对一关系,但我遇到了问题。 我有一张员工表和一张员工详细信息表。 在员工表中,我有一列 employeeId,在表 EmployeeDetail 中,我有一列 employeeId。 因此,当我向表中添加员工外键时,员工详细信息会自动增加。

这是我的实体:

Employee:

@OneToOne(mappedBy = "employee", cascade = CascadeType.ALL)
private EmployeeDetail employeeDetail;

EmployeeDetail:

@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "employeeId")
private Employee employee;

这是我的 class EmployeeServiceImpl也涉及保存Employee和EmployeeDetail的方法。

public Employee saveEmployee(Employee employee) {

    EmployeeDetail employeeDetail = employee.getEmployeeDetail();
    employeeDetail.setEmployee(employee);
    employee = employeeRepository.save(employee);
    return employee;

}

在 EmployeeController 中,我有两种方法来显示添加新员工的表单和存储新员工:

 @GetMapping("/showFormForAdd")
public String showFormForAdd(Model theModel) {

    // create model attribute to bind form data
    Employee theEmployee = new Employee();

    theModel.addAttribute("employee", theEmployee);

    return "addNewEmployeeForm";
}

@RequestMapping(value = "/addNewEmployee",method = RequestMethod.POST)
@ResponseBody
public Employee addNewEmployee(@ModelAttribute("employee") @RequestBody Employee employee) {
    Employee employeeResponse = employeeService.saveEmployee(employee);
    return employeeResponse;
}

这只是用于添加新员工的.jsp表单的一部分:

 <form:form action="addNewEmployee" modelAttribute="employee" method="POST">

如您所见,我的 model 属性是employee ,但在我的.jsp文件中无法识别。

我可以用什么方法修复它? 那么当我创建新员工时,他的 ID 会自动存储在 EmployeeDetail 中吗? 或者我如何将数据添加到我的相关表(EmployeeDetail)?

我不知道如何在保存员工时将员工 ID 直接存储在详细信息表中,但我会做的是

  1. 创建员工表格,通过员工controller处理,如下所示
    @GetMapping("/add")
    public String handleEmployeeForm(Model model) {
        model.addAttribute("employee", new Employee());
        return "formEmployee";
    }
    
    @PostMapping("/add")
    public String saveEmployee(@ModelAttribute("employee") Employee employee, Errors errors) {
        if(errors.hasErrors()) {
            return "formEmployee";
        }
        this.employeeService.save(employee);
        return "redirect:/employee/list";
    }

    @GetMapping("/list")
    public String listEmployees(Model model) {
        model.addAttribute("employees", this.employeeService.findAll());
        return "listEmployee";
    }

  1. 提供链接以添加员工的员工详细信息。 我通过一个列出所有员工的页面(检查 EmployeeController 的 /employee/list API)来完成此操作。
<a th:href="@{/employeeDetails/add/{employeeId}(employeeId=${employee.id})}" 
    th:each="employee : ${employees}"><span th:text="${employee.employeeEmail}"></span></a>
  1. 创建一个员工详细信息表单,将员工 ID 存储为表单中的隐藏字段,通过员工详细信息 controller 处理,如下所示。
<input type="hidden"
                    class="form-control" th:field="*{employee.id}"/>

员工详情 Controller

    @GetMapping("/add/{employeeID}")
    public String handleEmployeeDetailsForm(@PathVariable long employeeID, Model model) {
        //create dummy employee 
        Employee employee = new Employee();
        //set id received from request to this employee object
        employee.setId(employeeID);
        
        EmployeeDetails employeeDetails = new EmployeeDetails();
        //set dummy employee object    
        employeeDetails.setEmployee(employee);
        model.addAttribute("employeeDetails", employeeDetails);
        return "formEmployeeDetails";
    }
    
    @PostMapping("/add")
    public String saveEmployeeDetails(@ModelAttribute EmployeeDetails employeeDetails, Errors errors) {
        if(errors.hasErrors()) {
            return "formEmployeeDetails";
        }

        //fetch actual employee object from database
        Employee employee = this.employeeService.findById(employeeDetails.getEmployee().getId());

        //set to employee details object
        employeeDetails.setEmployee(employee);

        //save employee details object
        this.employeeDetailsService.save(employeeDetails);
        return "redirect:/listEmployeeDetails";
    }

编辑 1
实现预期结果的另一种方法是修改员工和员工详细信息类,如下所示
员工

@OneToOne(mappedBy = "employee", cascade = CascadeType.ALL)
@PrimaryKeyJoinColumn
private EmployeeDetail employeeDetail;

@PrimaryKeyJoinColumn 注释告诉 Employee 的主键将用作 EmployeeDetails 中的外键。
 EmployeeDetail @OneToOne @MapsId private Employee employee;

您将在此处将 EmployeeDetails 保存为其拥有方(我们在 Employee 中定义了 mappedBy),并且它将包含对 Employee 的外键引用。

员工详情控制器

@GetMapping("/add") public String handleEmployeeForm(Model model) { EmployeeDetails employeeDetails = new EmplyeeDetails(); employeeDetails.setEmployee(new Employee()); model.addAttribute("employeeDetails", employeeDetails ); return "formEmployee"; } @PostMapping("/add") public String saveEmployee(@ModelAttribute("employeeDetails") EmployeeDetails employeeDetails) { this.employeeDetailsService.save(employeeDetails); return "redirect:/employee/add"; }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM