首页 > 解决方案 > 无法将数据存储到相关的表弹簧

问题描述

我有表employee和表employee_detail,我可以将数据添加到非相关表(employee),控制器工作正常,一切正常,但我无法实现代码,因此我可以将数据存储到相关表employee_detail

Employee:

@Entity
@Table(name="employee")
public class Employee {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "employeeId")
    private int id;

    @Column(name = "first_name")
    private String firstName;

    @Column(name = "last_name")
    private String lastName;

    @Column(name = "email")
    private String email;


    @OneToOne(mappedBy = "employee")
    private EmployeeDetail employeeDetail;


    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    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 String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public EmployeeDetail getEmployeeDetail() {
        return employeeDetail;
    }

    public void setEmployeeDetail(EmployeeDetail employeeDetail) {
        this.employeeDetail = employeeDetail;
    }

}

EmployeeDetail:

    @Entity
    @Table(name = "employee_detail")
    public class EmployeeDetail {
    
        @Id
        @GeneratedValue(strategy= GenerationType.AUTO)
        @Column(name="employee_detail_id")
        private int id;
    
        @Column(name="work_experience")
        private int workExperience;
    
        @Column(name="hobby")
        private String hobby;
    
        @Column(name="nationality")
        private String nationality;
    
        @OneToOne
        @JoinColumn(name="employeeId")
        private Employee employee;
    
    
    
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public int getWorkExperience() {
            return workExperience;
        }
    
        public void setWorkExperience(int workExperience) {
            this.workExperience = workExperience;
        }
    
        public String getHobby() {
            return hobby;
        }
    
        public void setHobby(String hobby) {
            this.hobby = hobby;
        }
    
        public String getNationality() {
            return nationality;
        }
    
        public void setNationality(String nationality) {
            this.nationality = nationality;
        }
    
        public Employee getEmployee() {
            return employee;
        }
    
        public void setEmployee(Employee employee) {
            this.employee = employee;
        }
    
    
    }

这就是我将数据存储到employee表中的方式:

`EmployeeController:`



 @Controller
@RequestMapping("/employee")
public class EmployeeController {

    @Autowired
    private EmployeeService employeeService;

    @GetMapping("/list")
    public String listEmployee(Model theModel) {

        // get customers from the service
        List<Employee> theEmployee = employeeService.listEmployee();

        // add the customers to the model
        theModel.addAttribute("employees", theEmployee);

        return "list-employee";
    }

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

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

        theModel.addAttribute("employee", theEmployee);

        return "addNewEmployeeForm";
    }

    @PostMapping("/addNewEmployee")
    public String addNewEmployee(@ModelAttribute("employee") Employee theEmployee) {

        // save the customer using our service
        employeeService.addNewEmployee(theEmployee);

        return "redirect:/employee/list";
    }

}

并形成addNewEmployeeForm:

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

    <table>
        <tbody>
        <tr>
            <td><label>First name:</label></td>
            <td><form:input path="firstName" /></td>
        </tr>

        <tr>
            <td><label>Last name:</label></td>
            <td><form:input path="lastName" /></td>
        </tr>

        <tr>
            <td><label>Email:</label></td>
            <td><form:input path="email" /></td>
        </tr>

        <tr>
            <td><label></label></td>
            <td><input type="submit" value="Save" class="save" /></td>
        </tr>


        </tbody>
    </table>

如何将数据从相关表存储到表中?我错过了什么?

我试过这样但不起作用:

 @Controller
@RequestMapping("/employeeDetail")
public class EmployeeDetailController {

    @Autowired
    private EmployeeDetailService employeeDetailService;


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

        // get customers from the service
        List<EmployeeDetail> theEmployeeDetail = employeeDetailService.listEmployeeDetail();

        // add the customers to the model
        theModel.addAttribute("employeeDetails", theEmployeeDetail);

        return "list-employeeDetail";
    }

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

        // create model attribute to bind form data
        EmployeeDetail theEmployeeDetail = new EmployeeDetail();

        theModel.addAttribute("employeeDetail", theEmployeeDetail);

        return "addNewEmployeeDetailForm";
    }

    @PostMapping("/addNewEmployeeDetail")
    public String addNewEmployeeDetail(@ModelAttribute("employeeDetail") EmployeeDetail theEmployeeDetail) {

        // save the customer using our service
        employeeDetailService.addNewEmployeeDetail(theEmployeeDetail);

        return "redirect:/employeeDetail/listEmployeeDetail";
    }


}

要求的代码:

 @Override
@Transactional
public void addNewEmployeeDetail(EmployeeDetail theEmployeeDetail) {
    employeeDetailDAO.addNewEmployeeDetail(theEmployeeDetail);
}

标签: javaspring

解决方案


假设您没有主动保存EmployeeDetail自己的实体而只保存Employee,则在旁边配置关系cascade属性,如下所示:@OneToOneEmployee

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

有了这个,您告诉 EntityManager 将所有操作(PERSIST、REMOVE、REFRESH、MERGE、DETACH)传播(级联)到相关实体。


除了上述更改之外,我还建议您迁移到 JPA,而不是自己处理 Hibernate 会话。

在 pom.xml 中包含 Spring Boot JPA 依赖项

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

创建两个存储库,每个实体一个,并将它们注入相应的服务(就像您对 DAO 所做的那样):

public interface EmployeeDAO extends JpaRepository<Employee, Integer> {
}


public interface EmployeeDetailDAO extends JpaRepository<EmployeeDetail, Integer> {
}

现在在您的服务中,您可以在这些存储库上调用几个默认方法,例如findAll()save()。在您的情况下,您将执行以下操作:

@Override
@Transactional
public void addNewEmployee(Employee theEmployee) {
    employeeDAO.save(theEmployee);
}

您可以在https://www.baeldung.com/the-persistence-layer-with-spring-and-jpahttps://www.baeldung.com/spring-data-repositories查看更多详细信息。

EmployeeDetail请记住,当您从表单中收到它时,您将很难直接保存。原因是您需要设置Employee属性,否则将设置列中的外键,employeeId因此您将收到 SQL 错误。


推荐阅读