我在自己的spring数据JPA代码中具有描绘员工和经理关系的自我加入关系,并通过REST端点公开了它。
这是我的EmployeeController
@Controller
@RequestMapping(path = "/employee")
public class EmployeeController {
@Autowired
private EmployeeRepository employeeRepository;
@PostMapping
public Employee addNewUser(@RequestBody Employee employee) {
return employeeRepository.save(employee);
}
@GetMapping
public @ResponseBody Iterable<Employee> getAllUsers() {
// This returns a JSON or XML with the users
return employeeRepository.findAll();
}
}
这是员工实体
@Entity
@Table(name = "EMPLOYEE")
public class Employee {
@Id
@Column(name = "id")
@GeneratedValue
private Long id;
@Column(name = "fname")
private String fname;
@Column(name = "lname")
private String lname;
@ManyToOne(cascade = { CascadeType.ALL })
@JoinColumn(name = "manager_id")
private Employee manager;
@OneToMany(mappedBy = "manager")
private Set<Employee> subordinates = new HashSet<Employee>();
//getters and setters
}
现在,当我向POST
端点提交/employee
请求时,该请求如下
POST /employee
{
"fname":"akash",
"lname":"xavier",
"manager":{
"fname":"kiran",
"lname":"Kumar"
}
}
它正在按预期在数据库中创建行
mysql> select * from employee;
+----+----------+---------+------------+
| id | fname | lname | manager_id |
+----+----------+---------+------------+
| 20 | kiran | Kumar | NULL |
| 19 | akash | xavier | 20 |
+----+----------+---------+------------+
现在的问题是我想在请求下方提交
POST /employee
{
"fname":"Vipul",
"lname":"Kumar",
"manager":{
"fname":"kiran",
"lname":"Kumar"
}
}
但不希望再次创建Kiran Kumar
经理。
答案 0 :(得分:0)
对于您提供的用例,没有开箱即用的解决方案。您需要使用以下名称手动测试现有经理的姓名:
@PostMapping
public Employee addNewUser(@RequestBody Employee employee) {
return employeeService.create(employee);
}
EmployeeService.create()
的实现方式如下:
@Transactional
public void create(Employee employee) {
Employee manager = Optional.ofNullable(employee.getManager())
.flatMap(managerFromRequest -> employeeRepository.findByFnameAndLname(managerFromRequest.getFname(), managerFromRequest.getLname())
.ifPresent(Employee:setManager);
employeeRepository.save(employee);
}
和public Optional<Employee> findByFnameAndLname(String fname, String lname)
在EmployeeRepository
上声明。
作为旁注:
@ManyToOne(cascade = { CascadeType.ALL })
是错误的。特别是,CascadeType.REMOVE
对于@ManyToOne
关联没有意义fname
和lname
足以唯一地标识Employee
吗?有时候,人们恰好有相同的名字