删除多对多关联时出现问题

发布于 2025-01-20 18:48:32 字数 3200 浏览 1 评论 0原文

@entity
@table(name = "users")
public class User {

@Id
private Long id;

private String name;

@ManyToMany(cascade = {PERSIST, MERGE})
@JoinTable(name = "user_following",
        joinColumns = {@JoinColumn(name = "user_id")},
        inverseJoinColumns = {@JoinColumn(name = "user_following_id")})
private List<User> following;

@ManyToMany(cascade = {PERSIST, MERGE})
@JoinTable(name = "user_followers",
        joinColumns = {@JoinColumn(name = "user_id")},
        inverseJoinColumns = {@JoinColumn(name = "user_follower_id")})
private List<User> followers;

//some other fields, getters and setters

public void follow(User user) {
    following.add(user);
    user.acceptFollower(this);
}

public void acceptFollower(User user) {
    followers.add(user);
}
}

我们有三个表:

  • 用户
  • user_following
  • user_followers

可以想象拥有此实体,并且您正在实现以下&amp;追随者功能。 我们必须向用户 - Rick&amp;汤姆。

User rick = new User(1, "rick");
User tom = new User(2, "tom");
rick.follow(tom);

调用方法 - rick.follow(tom); 我们将以以下方式填充表

- “用户”

ID名称
1rick
2tom

表 - “ user_following”

user_id user_iduser_following_id_id
12

表 - “ user_followers”

user_id user_id user_follower_iduser_follower_id
21

到目前我尝试删除用户。

例如:

userrepository.deletebyid(1)

JPA给出了错误 - 更新或在表“用户”上删除违反外键约束“ FK1YG7XQW2KFX6N2196O0GR3OBC”表“ User_followers”上 Nomention(ID)=(1)仍然从表“ user_followers”引用。

JPA无法删除,因为它会生成错误的SQL。

Hibernate: 
   select
       user0_.id as id1_5_,
       user0_.first_name as first_na5_5_,
   from
       users user0_ 
   where
       user0_.username=?
Hibernate: 
   delete 
   from
       user_followers 
   where
       user_id=?
Hibernate: 
   delete 
   from
       user_following 
   where
       user_id=?
Hibernate: 
   delete 
   from
       users 
   where
       id=?

我想删除用户-ID = 1的Rick

由于错误的SQL而发生错误。 当我们删除用户 - 'rick', 我们首先从“ user_following”和“ user_followers”表中删除“ rick”表。

看看这个说法。

Hibernate: 
    delete 
    from
        user_followers 
    where
        user_id=?

错误是由于此语句引起的,因为 用户我们删除的用户对应于“ user_followers”表的(user_following_id)列, 不是“ user_id”列。

正确的SQL语句必须是:

Hibernate: 
    delete 
    from
        user_followers 
    where
        user_following_id=?

有没有办法解决此问题?

@entity
@table(name = "users")
public class User {

@Id
private Long id;

private String name;

@ManyToMany(cascade = {PERSIST, MERGE})
@JoinTable(name = "user_following",
        joinColumns = {@JoinColumn(name = "user_id")},
        inverseJoinColumns = {@JoinColumn(name = "user_following_id")})
private List<User> following;

@ManyToMany(cascade = {PERSIST, MERGE})
@JoinTable(name = "user_followers",
        joinColumns = {@JoinColumn(name = "user_id")},
        inverseJoinColumns = {@JoinColumn(name = "user_follower_id")})
private List<User> followers;

//some other fields, getters and setters

public void follow(User user) {
    following.add(user);
    user.acceptFollower(this);
}

public void acceptFollower(User user) {
    followers.add(user);
}
}

We have three tables:

  • users
  • user_following
  • user_followers

Imagine having this entity and you are implementing following & followers functionality.
We have to users - rick & tom.

User rick = new User(1, "rick");
User tom = new User(2, "tom");
rick.follow(tom);

After calling method - rick.follow(tom);
We will populate our tables in the following way

Table - "users"

idname
1rick
2tom

Table - "user_following"

user_iduser_following_id
12

Table - "user_followers"

user_iduser_follower_id
21

So far, everything works just great but the problem starts when i try to delete users.

For example:

userRepository.deleteById(1)

JPA gives an error -
update or delete on table "users" violates foreign key constraint "fk1yg7xqw2kfx6n2196o0gr3obc" on table "user_followers"
Подробности: Key (id)=(1) is still referenced from table "user_followers".

JPA cannot delete because it generates a wrong sql.

Hibernate: 
   select
       user0_.id as id1_5_,
       user0_.first_name as first_na5_5_,
   from
       users user0_ 
   where
       user0_.username=?
Hibernate: 
   delete 
   from
       user_followers 
   where
       user_id=?
Hibernate: 
   delete 
   from
       user_following 
   where
       user_id=?
Hibernate: 
   delete 
   from
       users 
   where
       id=?

I want to delete user - rick whose id = 1

The error happens due to wrong sql.
When we delete user - 'rick',
we first delete 'rick' from "user_following" and "user_followers" tables.

Look at the this statement.

Hibernate: 
    delete 
    from
        user_followers 
    where
        user_id=?

The error happens due to this statement because the
user we are deleting corresponds to the (user_following_id) column of the "user_followers" table,
not "user_id" column.

The right sql statement must be:

Hibernate: 
    delete 
    from
        user_followers 
    where
        user_following_id=?

Is there a way how to fix this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

携君以终年 2025-01-27 18:48:32

请勿创建user_followers作为表,而是在表 view 上创建它, user_following。视图定义仅逆转列名。我不知道您的模糊经理,所以我只会提供所需的SQL。 (请参阅

create table users( id    integer primary key 
                  , name  text 
                  ) ; 
                 
 create table user_following( user_id   integer 
                                        references users(id) 
                                        on delete cascade 
                            , user_following_id integer 
                                        references users(id) 
                                        on delete cascade
                            , constraint  user_following_pk 
                                          primary key (user_id,user_following_id)
                            ) ; 
                            
create view user_followers as 
       select user_following_id as user_id 
            , user_id           as user_follower_id
  from user_following; 

Do not create user_followers as a table, instead create it as a view on the table user_following. The view definition merely reverses the column names. I do not know your obscurification manager so I will just supply the needed SQL. (see demo).

create table users( id    integer primary key 
                  , name  text 
                  ) ; 
                 
 create table user_following( user_id   integer 
                                        references users(id) 
                                        on delete cascade 
                            , user_following_id integer 
                                        references users(id) 
                                        on delete cascade
                            , constraint  user_following_pk 
                                          primary key (user_id,user_following_id)
                            ) ; 
                            
create view user_followers as 
       select user_following_id as user_id 
            , user_id           as user_follower_id
  from user_following; 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文