【问题标题】:ids for this class must be manually assigned before calling save(): com.employeesService.EmployeesService.model.Employee必须在调用 save() 之前手动分配此类的 ID:com.employeesService.EmployeesService.model.Employee
【发布时间】:2021-12-22 13:57:23
【问题描述】:

Department 和 Employee 之间存在多对多关系 Image of Employee schema

我将复合键更改为 Embeddable 类,然后将该类作为我的 DepartmentEmployee 类的 Id 调用后,我的问题就出现了

这些是我的课程:

部门员工编号:

@Embeddable
public class DepartmentEmployeeId implements Serializable {

@Column(name = "dept_no")
private String deptNo;

@Column(name = "emp_no")
private Long empNo;

public DepartmentEmployeeId() {
}

public DepartmentEmployeeId(String deptNo, Long empNo) {
    this.deptNo = deptNo;
    this.empNo = empNo;
}

public String getDeptNo() {
    return deptNo;
}

public void setDeptNo(String deptNo) {
    this.deptNo = deptNo;
}

public Long getEmpNo() {
    return empNo;
}

public void setEmpNo(Long empNo) {
    this.empNo = empNo;
}

@Override
public boolean equals(Object o) {
    if (this == o) return true;

    if (o == null || getClass() != o.getClass())
        return false;

    DepartmentEmployeeId that = (DepartmentEmployeeId) o;
    return Objects.equals(deptNo, that.deptNo) &&
            Objects.equals(empNo, that.empNo);
}

@Override
public int hashCode() {
    return Objects.hash(deptNo, empNo);
}

} 部门:

@Entity
@Table(name = "departments")
public class Department {
    @Id
    @Column(name = "dept_no")
    private String deptNo;
    @Column(name = "dept_name")
    private String deptName;

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "department", orphanRemoval = true)
    @JsonIgnore
    private List<DepartmentEmployee> departmentEmployees = new ArrayList<>();

    public String getDeptNo() {
        return deptNo;
    }

    public void setDeptNo(String deptNo) {
        this.deptNo = deptNo;
    }

    public String getDeptName() {
        return deptName;
    }

    public void setDeptName(String deptName) {
        this.deptName = deptName;
    }

    public void addEmployee(DepartmentEmployee departmentEmployee) {
        Employee employee=new Employee();
        departmentEmployee = new DepartmentEmployee(this, employee);
        departmentEmployees.add(departmentEmployee);
    }

    public List<DepartmentEmployee> getDepartmentEmployees() {
        return departmentEmployees;
    }
}

员工:

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

    public enum Gender {M, F}

    @Id
    private Long empNo;
    @Column(name = "birth_date")
    private LocalDate birthDate;
    @Column(name = "first_name")
    private String firstName;
    @Column(name = "last_name")
    private String lastName;
    @Enumerated(EnumType.STRING)
    @Column(name = "gender")
    private Gender gender;
    @Column(name = "hire_date")
    private LocalDate hireDate;
    @OneToMany(cascade = CascadeType.ALL)
    @JoinColumn(name = "emp_no")
    @JsonIgnore
    private List<Salary> salaries = new ArrayList<>();

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "employee",orphanRemoval = true)
    @JsonIgnore
    private List<DepartmentEmployee> departmentEmployees = new ArrayList<>();


    public List<Salary> getSalaries() {
        return salaries;
    }

    public Long getEmpNo() {
        return empNo;
    }

    public void setEmpNo(Long empNo) {
        this.empNo = empNo;
    }

    public LocalDate getBirthDate() {
        return birthDate;
    }

    public void setBirthDate(LocalDate birthDate) {
        this.birthDate = birthDate;
    }

    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 Gender getGender() {
        return gender;
    }

    public void setGender(Gender gender) {
        this.gender = gender;
    }

    public LocalDate getHireDate() {
        return hireDate;
    }

    public void setHireDate(LocalDate hireDate) {
        this.hireDate = hireDate;
    }

    public void assignSalary(Salary salary) {
        salaries.add(salary);
    }

    public List<DepartmentEmployee> getDepartmentEmployees() {
        return departmentEmployees;
    }

}

部门员工

@Entity
@Table(name = "dept_emp")
public class DepartmentEmployee {
    @EmbeddedId
    private DepartmentEmployeeId id;

    @ManyToOne(fetch = FetchType.LAZY)
    @MapsId("deptNo")
    private Department department;

    @ManyToOne(fetch = FetchType.LAZY)
    @MapsId("empNo")
    private Employee employee;

    @Column(name = "from_date")
    private LocalDate fromDate;
    @Column(name = "to_date")
    private LocalDate toDate;

    public DepartmentEmployee() {
    }

    public DepartmentEmployee(Department department, Employee employee) {
        this.department=department;
        this.employee=employee;
        this.id = new DepartmentEmployeeId(department.getDeptNo(), employee.getEmpNo());
    }

    public DepartmentEmployeeId getId() {
        return id;
    }

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

    public Department getDepartment() {
        return department;
    }

    public void setDepartment(Department department) {
        this.department = department;
    }

    public Employee getEmployee() {
        return employee;
    }

    public void setEmployee(Employee employee) {
        this.employee = employee;
    }

    public LocalDate getFromDate() {
        return fromDate;
    }

    public void setFromDate(LocalDate fromDate) {
        this.fromDate = fromDate;
    }

    public LocalDate getToDate() {
        return toDate;
    }

    public void setToDate(LocalDate toDate) {
        this.toDate = toDate;
    }
}

我的服务添加方法:

@Override
@Transactional
public Employee addEmployeeToDepartment(String deptNo, Long empNo, DepartmentEmployee departmentEmployee) {
    Department department = this.departmentRepository.findById(deptNo).orElseThrow(() -> new DepartmentNotFoundException(deptNo));

    Employee employee = this.employeeRepository.findById(empNo).orElseThrow(() -> new EmployeeNotFoundException(empNo));
    departmentEmployee.setId(new DepartmentEmployeeId(department.getDeptNo(), employee.getEmpNo()));
    departmentEmployee.setDepartment(department);
    departmentEmployee.setEmployee(employee);
    department.addEmployee(departmentEmployee);
    this.departmentRepository.save(department);
    return employee;
}

【问题讨论】:

  • edit发帖并添加DepartmentEmployeeId类。

标签: java spring-boot hibernate jpa


【解决方案1】:

我发现了我的问题,就是在这个方法上:

public void addEmployee(DepartmentEmployee departmentEmployee) {
        Employee employee=new Employee();
        departmentEmployee = new DepartmentEmployee(this, employee);
        departmentEmployees.add(departmentEmployee);
    }

我正在创建一个新员工,但我没有给它一个 ID,这就是我所要做的:

public void addEmployee(DepartmentEmployee departmentEmployee) {
        departmentEmployees.add(departmentEmployee);
    }

【讨论】:

    【解决方案2】:

    很简单……

    在您拥有的 Employee 类中

    @Entity
    @Table(name = "employees")
    public class Employee {
    
        public enum Gender {M, F}
    
        @Id
        //Add @GenerateValue here
        private Long empNo;
    

    您在@Id 下方缺少@GeneratedValue 注释。 更多详情请见here

    【讨论】:

    • 不,因为在我的任务中,我需要在可嵌入的东西之前将 deptNo 和 empNo 作为非生成值,我有一个带有 ad IdClass 的复合键,它曾经可以正常工作,但是当我更改为嵌入式类现在我似乎找不到让它工作的方法
    • 我说的是 Employee 类而不是 DepartmentEmployee 类。
    • 我知道,但是如果您查看我发布的架构,您会发现我还有其他关系,我需要将 empNo 作为非自动生成的值
    • Hmm ...帖子标题中的错误消息说...在调用save()之前:com.employeesService.EmployeesService.model.Employee ...所以这意味着问题出在Employee没有课?
    猜你喜欢
    • 2011-07-24
    • 2013-04-15
    • 2015-11-18
    • 2011-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-31
    • 2016-03-22
    相关资源
    最近更新 更多