I have a manyToMany relationship between Department and Employee Image of Employee schema
My problem came after i changed the composited keys to an Embeddable class and then calling that class as an Id on my DepartmentEmployee class
These are my classes:
DepartmentEmployeeId:
@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);
}
} Department:
@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;
}
}
Employee:
@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;
}
}
Department Employee
@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;
}
}
My Service add method:
@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;
}
CodePudding user response:
I found my problem, it was at this method:
public void addEmployee(DepartmentEmployee departmentEmployee) {
Employee employee=new Employee();
departmentEmployee = new DepartmentEmployee(this, employee);
departmentEmployees.add(departmentEmployee);
}
I was creating a new employee and i was not giving it an id, this is all i had to do:
public void addEmployee(DepartmentEmployee departmentEmployee) {
departmentEmployees.add(departmentEmployee);
}
CodePudding user response:
Its very simple ...
In the Employee class you have
@Entity
@Table(name = "employees")
public class Employee {
public enum Gender {M, F}
@Id
//Add @GenerateValue here
private Long empNo;
You are missing a @GeneratedValue annotation just below the @Id
.
For more details see here.