休眠自引用关系外键约束问题

时间:2019-04-30 11:55:31

标签: java hibernate spring-boot

我正在设置一个Springboot API,该API使用休眠模式与数据库进行通信。我有一个用户表,每个用户都应该可以关注其他用户。我没有休眠的经验,所以过了一会儿,我似乎有了一些工作,除了如果该特定用户被其他用户关注,我无法删除该用户。这是由于外键约束。

这是用户的样子:

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(unique = true)
    @JsonProperty
    private int id;

    @Column(unique = true)
    @JsonProperty
    private String email;

    @Column
    @JsonProperty
    private String hashedSaltedPassword;

    @Column
    @JsonProperty
    private String salt;

    @Column
    @JsonProperty
    private String firstName;

    @Column
    @JsonProperty
    private String lastName;

    @JsonProperty
    @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinTable(name = "User_Follows", schema = "todo", joinColumns=@JoinColumn(name="user_id"))
    private List<User> follows;

这将创建用户表和一个名为User_Follows的单独表。该表具有user_id和follows_id,即跟随的userId。这几乎就是我想要的。

只要该用户没有被其他用户关注(只要该用户的userId不在follows_id列中),删除该用户就可以完美地工作。

但如果是,它将给出以下错误:

The DELETE statement conflicted with the REFERENCE constraint "FKc38v25qxktm9b0r7lg1s2t1tl". The conflict occurred in database "dbi390100_db", table "todo.User_Follows", column 'follows_id'.

这不应该发生,我想要的是,每当删除用户时,都会删除User_Follows表中userId存在的所有行。

有解决方案吗?

1 个答案:

答案 0 :(得分:0)

有两种方法可以实现所需的目标。

  • 使用另一个字段定义mappedBy属性,以使休眠状态了解整个关系,例如:
@ManyToMany(targetEntity = User.class, mappedBy = "follows")
private List<User> followers = new ArrayList<>();

您可以看看this other question

  • 或者您可以在用户类中创建@PreRemove方法来手动删除用户的所有引用:
@PreRemove
private void removeFromFollowers() {
   for (User user : followers) {
       user.removeFollowed(this);
   }
}