Java 正在删除实体@OneToMany@ManyToOne。键仍然从表中引用

Java 正在删除实体@OneToMany@ManyToOne。键仍然从表中引用,java,hibernate,hql,hibernate-mapping,hibernate-criteria,Java,Hibernate,Hql,Hibernate Mapping,Hibernate Criteria,我有两个实体-User和Song: User.class: @实体 @表(name=“users”) 公共类用户{ @身份证 @列(name=“user\u id”) @GeneratedValue(策略=GenerationType.IDENTITY) 私人长id; @列(name=“first_name”) 私有字符串名; @列(name=“last_name”) 私有字符串lastName; @列(name=“login”,unique=true) 私有字符串登录; @列(name=“pa

我有两个实体-
User
Song

User.class:

@实体
@表(name=“users”)
公共类用户{
@身份证
@列(name=“user\u id”)
@GeneratedValue(策略=GenerationType.IDENTITY)
私人长id;
@列(name=“first_name”)
私有字符串名;
@列(name=“last_name”)
私有字符串lastName;
@列(name=“login”,unique=true)
私有字符串登录;
@列(name=“password”)
私有字符串密码;
@列(name=“token”)
专用UUID令牌;
@OneToMany(cascade=CascadeType.ALL,fetch=FetchType.EAGER)
@可接合(
name=“用户\歌曲”,
joinColumns=@JoinColumn(
name=“u_id”,
referencedColumnName=“用户\u id”
),
inverseJoinColumns=@JoinColumn(
name=“s_id”,
referencedColumnName=“宋_id”
)
)
私有列表歌曲=新建ArrayList();
}
Song.class:

@实体
@表(name=“songs”)
公开课歌曲{
@身份证
@列(name=“song\u id”)
@GeneratedValue(策略=GenerationType.IDENTITY)
私人长id;
@列(name=“song_title”)
私人弦乐歌曲名称;
@列(name=“composer\u name”)
@ElementCollection(fetch=FetchType.EAGER)
@CollectionTable(name=“Composer”)
@OnDelete(action=OnDeleteAction.CASCADE)
@JoinColumn(name=“composer\u id”)
私人音乐作曲家;
@列(name=“作者姓名”)
@ElementCollection(fetch=FetchType.EAGER)
@CollectionTable(name=“单词的作者”)
@OnDelete(action=OnDeleteAction.CASCADE)
@JoinColumn(name=“authorOfWords\u id”)
私有集authorOfWords;
@专栏(name=“song_艺术家”)
私人弦乐歌手;
@列(name=“song_计时”)
私人时间;
@manytone(cascade={CascadeType.PERSIST,CascadeType.MERGE,CascadeType.REFRESH})
@JoinColumn(name=“user\u id\u key”)
私人用户;
@列(name=“rate\u value”)
@ElementCollection(fetch=FetchType.EAGER)
@CollectionTable(name=“评级”)
@MapKeyColumn(name=“login”)
@OnDelete(action=OnDeleteAction.CASCADE)
@连接柱
私有最终映射评级=新HashMap();
@纵队
@ElementCollection(fetch=FetchType.EAGER)
@CollectionTable(name=“comment”)
@MapKeyColumn(name=“login”)
@OnDelete(action=OnDeleteAction.CASCADE)
@连接柱
私有最终映射注释=新HashMap();
}
我想删除歌曲,但不想删除用户

我试着这样删除它:

Query Query=session.createQuery(“删除歌曲s,其中s.user=:user和s.songTitle=:songTitle”);
query.setParameter(“用户”,用户);
query.setParameter(“songTitle”,songTitle);
query.executeUpdate()
但错误在于:

    Caused by: org.hibernate.exception.ConstraintViolationException: could not execute statement...
    Caused by: org.postgresql.util.PSQLException: ERROR: update or delete on table "songs" violates foreign key constraint "fka7me64vk6jtx81wt2ggbvm6ur" on table "users_songs"
     Key (song_id)=(28) is still referenced from table "users_songs".
据我所知,该问题是由于在扩展表中,由于连接
@OneToMany
而发生的
用户歌曲

我在STO中读到一个类似的问题,它说你需要断开连接

我执行了以下代码:

List collect=user.getSongs().stream().filter(s->!s.getsongtile().equals(songtile)).collect(Collectors.toList());
用户:setSongs(收集);
会话更新(用户);
Query Query=session.createQuery(“删除歌曲s,其中s.songTitle=:songTitle”);
query.setParameter(“songTitle”,songTitle);
query.executeUpdate();
这段代码有效,但我认为它不太正确。现在是问题。如何从用户中删除歌曲?条件是歌曲不应级联以删除用户


请帮我正确地解决这个问题。非常感谢。

您可以在表
用户歌曲上为
fka7me64vk6jtx81wt2ggbvm6ur
指定
的删除级联
,如下所示:

@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinTable(
   name = "users_songs",
   joinColumns = @JoinColumn(
      name = "u_id",
      referencedColumnName = "user_id"
   ),
   inverseJoinColumns = @JoinColumn(
      name = "s_id",
      referencedColumnName = "song_id"
   ),
   inverseForeignKey = @ForeignKey(
      name = "users_songs_songs_FK",  // fka7me64vk6jtx81wt2ggbvm6ur renamed to users_songs_songs_FK
      foreignKeyDefinition = "FOREIGN KEY (s_id) REFERENCES songs(song_id) ON DELETE CASCADE"
   )
)
private List<Song> songs = new ArrayList<>();
@OneToMany(cascade=CascadeType.ALL,fetch=FetchType.EAGER)
@可接合(
name=“用户\歌曲”,
joinColumns=@JoinColumn(
name=“u_id”,
referencedColumnName=“用户\u id”
),
inverseJoinColumns=@JoinColumn(
name=“s_id”,
referencedColumnName=“宋_id”
),
inverseForeignKey=@ForeignKey(
name=“users_songs_songs_FK”//fka7me64vk6jtx81wt2ggbvm6ur重命名为users_songs_FK
foreignKeyDefinition=“外键(s\u id)引用删除级联上的歌曲(song\u id)”
)
)
私有列表歌曲=新建ArrayList();
在数据库模式重新生成之后,您的初始查询应该可以按预期工作