java - 如何限制自加入中的重复记录
问题描述
我在我的 Spring Data JPA 代码中有描述员工和经理关系的自加入关系,并通过 REST 端点公开它。
这是我的员工控制器
@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
再次创建经理。
解决方案
对于您提供的用例,没有开箱即用的解决方案。您需要手动测试同名的现有管理器,类似于:
@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
? 有时,人们只是碰巧有相同的名字
推荐阅读
- python - 如何组合列表以创建两组特定的列表
- c# - 从另一个项目 SharePoint 2013 空值添加用户控件
- java - 使用 rumtimeexec 的意外 EOF 异常
- tableau-api - Tableau 仪表板与多个客户端共享
- css - 使用选项卡创建引导程序 4 向导,但按钮只能工作一次
- java - 即使在 Springboot 应用程序的过滤器中指定 Access-Control-Allow-Origin 标头后,也无法控制跨源请求
- android - 如何在 Android Studio 中添加标头搜索路径?
- c - 不知道为什么使用 scanf 时 while 循环的工作方式不同
- java - 无法使用页面工厂从 selenium 中的另一个测试类调用测试方法
- python - 为什么 pyproj.Proj 前向投影似乎不考虑经纬度起源?