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

时间:2014-06-03 11:29:36

标签: java jpa many-to-many

我有实体:

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

3 个答案:

答案 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中