java - 尝试删除记录时如何修复 Spring-Boot 中的“违反外键约束”。使用@ManyToMany
问题描述
我正在尝试从我的数据库中删除一些记录,但收到以下错误:“表“角色”上的更新或删除违反了表“users_role”上的外键约束“fk3qjq7qsiigxa82jgk0i0wuq3g””
我做了一些研究,发现这可能与我的一个关系被设置为 @ManyToMany 有关。
我尝试从本网站的其他示例中修改我的代码,但没有成功。
public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "users_id")
private long id;
@Column(name = "email")
@Email(message = "*Please provide a valid Email")
@NotEmpty(message = "*Please provide an email")
private String email;
@Column(name = "password")
@Length(min = 5, message = "*Your password must have at least 5 characters")
@NotEmpty(message = "*Please provide your password")
private String password;
@Column(name = "name")
@NotEmpty(message = "*Please provide your name")
private String name;
@Column(name = "surname")
@NotEmpty(message = "*Please provide your surname")
private String surname;
@Column(name = "active")
private int active;
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name = "users_role", joinColumns = @JoinColumn(name = "users_id"), inverseJoinColumns = @JoinColumn(name = "role_id"))
private Set<Role> roles;
@Column(name = "position")
private String position;
public class Role {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "role_id")
private int id;
public class UserController {
.
.
.
.
@GetMapping("/admin/deleteuser/{id}")
public String deleteUser(@PathVariable("id") long id, Model model) {
User user = userRepository.findById(Long.valueOf(id)).orElseThrow(() -> new IllegalArgumentException("Invalid user Id:" + id));
userRepository.delete(user);
model.addAttribute("users", userRepository.findAll());
return "/admin/show-users";
}
解决方案
问题似乎在这里:
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name = "users_role", joinColumns = @JoinColumn(name = "users_id"), inverseJoinColumns = @JoinColumn(name = "role_id"))
private Set<Role> roles;
特别是,CascadeType.ALL
意味着当您尝试删除 aUser
时,该删除将级联到 thatUser
的角色。您不太可能希望这样做,因为建立多对多而不是一对多的关系的全部意义在于多个用户可以拥有一个给定的角色。如果您尝试删除角色(无论是直接删除还是通过级联删除),有两种选择:
- 删除级联到具有相同角色的所有其他用户(然后返回所有这些用户的角色等,或
- 删除失败。
你看到了(2)。当您尝试删除角色时,报告的特定约束违规与表中其他用户的行有关。user_role
我不清楚您是否真的想将任何持久性操作从User
s 级联到分配Role
的 s。我倾向于不这么认为,在这种情况下,您根本不需要指定您的cascade
属性ManyToMany
:
@ManyToMany
@JoinTable(name = "users_role", joinColumns = @JoinColumn(name = "users_id"), inverseJoinColumns = @JoinColumn(name = "role_id"))
private Set<Role> roles;
但是,如果您进行级联,那么您需要指定您想要的各个级联类型,省略CascadeType.REMOVE
,可能类似于
@ManyToMany(cascade = {CascadeType.DETACH, CascadeType.REFRESH})
@JoinTable(name = "users_role", joinColumns = @JoinColumn(name = "users_id"), inverseJoinColumns = @JoinColumn(name = "role_id"))
private Set<Role> roles;
推荐阅读
- java - 你能推荐我在控制器服务中使用的通用名称吗?
- android - 如何将 google mlkit Face 对象转换为位图
- javascript - 有什么方法可以自定义“react-owl-carousel”的导航箭头和点在使用 css 或 js 的反应中?
- python-3.x - 如果 Nneighbourclassifier 中 n_neighour=4 的值怎么办?
- go - 是否可以在 Golang 中为 nil 起别名
- arrays - MS Excel - 带循环的 SumProduct 公式
- c# - 当返回类型不是 ActionResult 时如何返回 BadRequest?
- javascript - 如何正确地将 prop 从 laravel 8 刀片传递到 vue 3 组件
- laravel - Laravel 事件未记录到 Redis
- reactjs - 刷新页面时不会加载 Firebase 实时数据