Java JPA @ManyToMany - 无法删除或更新父行:外键约束失败

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24014036/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 09:44:21  来源:igfitidea点击:

JPA @ManyToMany - Cannot delete or update a parent row: a foreign key constraint fails

javajpamany-to-many

提问by James P.

I have the Entities:

我有实体:

@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>();

When doing a delete/remove the following Exception is thrown:

执行删除/移除操作时会抛出以下异常:

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`))

It seems there is an issue with the generated join table and foreign keys.

生成的连接表和外键似乎存在问题。

How can this be fixed so a Role can be deleted ?

如何修复此问题以便可以删除角色?



Edit:

编辑:

Exported SQL shows this:

导出的 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`)
)

采纳答案by AlexR

Think how can JPA solve the many-to-many relationship.

想一想JPA如何解决多对多的关系。

I guess it creates table User, table Roleand table user_rolethat contains references (foreign keys) to user and to role.

我猜它会创建 table User, tableRole和 table user_role,其中包含对用户和角色的引用(外键)。

Now, if you want to remove role you have to remove all references of this role being held by users. In order to do this you have to iterate over all users that have such role and remove it from this user's role list. Then you can safely remove the role.

现在,如果您想删除角色,您必须删除用户持有的该角色的所有引用。为此,您必须遍历所有具有此类角色的用户并将其从该用户的角色列表中删除。然后您可以安全地删除该角色。

BTW once you solve this problem you will probably have the next one with Permission. So, if i were you I'd temporarily remove the permissionsfield from Rolemake the role deletion working and then restore the permissionsto sole new problems if exist.

顺便说一句,一旦你解决了这个问题,你可能会有下一个Permission。所以,如果我是你,我会暂时删除该permissions字段,Role使角色删除工作,然后恢复permissions到唯一的新问题(如果存在)。

回答by Genzotto

Try adding CascadeType.REMOVEto your mappings:

尝试添加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>();

In this way, children entities don't have to be removed before parent, so you could delete a Role without deleting its Permissions before.

这样,子实体不必在父实体之前删除,因此您可以删除角色而不删除其权限。

回答by user9869932

I got this one fixed by,

我把这个修好了,

changing some table names (maybe those names were reserved words in MySQL?)

更改一些表名(也许这些名称是 MySQL 中的保留字?)

e.g: "admins" instead of "admin"

例如:“管理员”而不是“管理员”

@Table(name = "admins")
public class Admin extends TrackedEntity {

}

and by changing:

并通过改变:

spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect

for:

为了:

spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect

in application.properties

在 application.properties 中