我有实体:
@Entity
public class User {
@ManyToMany(cascade=CascadeType.PERSIST, fetch=FetchType.EAGER)
private List<Role> roles = new ArrayList<Role>();
@Entity
public class Role {
@ManyToMany(cascade=CascadeType.PERSIST, fetch=FetchType.EAGER)
private Set<Permission> permissions = new HashSet<Permission>();
执行删除/删除时,抛出以下异常:
Caused by: com.mysql.jdbc.exceptions.MySQLIntegrityConstraintViolationException: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`user_role`, CONSTRAINT `FK_USER_ROLE_roles_ID` FOREIGN KEY (`roles_ID`) REFERENCES `role` (`ID`))
生成的连接表和外键似乎存在问题。
如何解决这个问题,以便删除角色?
编辑:
导出的SQL显示了这个:
CREATE TABLE IF NOT EXISTS `user_role` (
`User_ID` bigint(20) NOT NULL,
`roles_ID` bigint(20) NOT NULL,
PRIMARY KEY (`User_ID`,`roles_ID`),
KEY `FK_USER_ROLE_roles_ID` (`roles_ID`)
)
答案 0 :(得分:7)
想想JPA如何解决多对多关系。
我猜它会创建表User
,表Role
和表user_role
,其中包含对用户和角色的引用(外键)。
现在,如果要删除角色,则必须删除用户持有的此角色的所有引用。为此,您必须迭代具有此类角色的所有用户,并将其从此用户的角色列表中删除。然后,您可以安全地删除该角色。
一旦你解决了这个问题,你可能会有Permission
的下一个问题。所以,如果我是你,我会暂时从permissions
删除Role
字段,使角色删除工作,然后将permissions
恢复为唯一的新问题(如果存在)。
答案 1 :(得分:2)
尝试将CascadeType.REMOVE
添加到您的映射中:
@ManyToMany(cascade= {CascadeType.PERSIST, CascadeType.REMOVE}, fetch=FetchType.EAGER)
private List<Role> roles = new ArrayList<Role>();
@ManyToMany(cascade= {CascadeType.PERSIST, CascadeType.REMOVE}, fetch=FetchType.EAGER)
private Set<Permission> permissions = new HashSet<Permission>();
通过这种方式,儿童实体不必在父母之前删除,因此您可以删除角色而不删除其权限。
答案 2 :(得分:0)
我已经解决了这个问题,
更改一些表名(也许这些名称在MySQL中是保留字?)
例如:“管理员”而不是“管理员”
@Table(name = "admins")
public class Admin extends TrackedEntity {
}
并通过更改:
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect
针对:
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
在application.properties中