带有CascadeType.ALL的ManyToMany导致传递的Detched实体持久化

时间:2019-02-13 19:48:40

标签: java spring hibernate jpa

我与用户和角色有很多关系。用户是关系的所有者,并且具有CascadeType.ALL。在为数据库设置种子时,我首先创建用户,创建角色并将角色分配给用户。之后,我将所有用户保存在存储库中。

我可以想象,由于我要保存用户,因此角色也将由于级联类型而保存在数据库中,但是我遇到的错误是标题中提到的错误。

用户:

@Entity
public class User {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long id;

@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(
        name = "users_roles",
        joinColumns = @JoinColumn(
                name = "user_id", referencedColumnName = "id"),
        inverseJoinColumns = @JoinColumn(
                name = "role_id", referencedColumnName = "id"))
private List<Role> roles;   

角色:

@Entity
public class Role {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

@JsonIgnore
@ManyToMany
private List<User> users;

用于播种数据库的代码:

        User user1= new User();
        User user2= new User();

        Role role1 = new Role();
        Role role2 = new Role();

        user1.addRole(role1);
        user2.addRole(role1);
        user2.addRole(role2);

        role1.addUser(user1);
        role1.addUser(user2);
        role2.addUser(user2);

        userRepository.save(user1);
        userRepository.save(user2);

感谢您的帮助!

编辑:我发现仅当我向同一用户添加多个角色并更新了代码时,才会出现问题。

2 个答案:

答案 0 :(得分:0)

这个例子对我有用,那里也不例外。请分享更多信息:休眠版本,数据库和您正在运行的实际代码。

答案 1 :(得分:0)

您在此处进行级联是错误的。完全将Cascade.ALL包含在多对多集合上是没有意义的,因为您可以拥有跨用户共享的角色。

休眠状态试图告诉您的是,您已经拥有一个具有关联ID的角色,并且您试图在同一角色上坚持存在。

您需要弄清楚如何管理您的角色。您有两种选择:

  1. 删除级联。
  2. 将托管角色重新分配给您的用户2,这样您就不会使用分离的角色。

我个人将删除Cascade.ALL。 IMO这是错误的。