[英]Deleting Entities @OneToMany @ManyToOne. Key is still referenced from table
I have two entities - User
and Song
:我有两个实体 -
User
和Song
:
User.class:用户.class:
@Entity
@Table(name = "users")
public class User {
@Id
@Column(name = "user_id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "first_name")
private String firstName;
@Column(name = "last_name")
private String lastName;
@Column(name = "login",unique = true)
private String login;
@Column(name = "password")
private String password;
@Column(name = "token")
private UUID token;
@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"
)
)
private List<Song> songs = new ArrayList<>();
}
Song.class:歌曲.class:
@Entity
@Table(name = "songs")
public class Song {
@Id
@Column(name = "song_id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "song_title")
private String songTitle;
@Column(name = "composer_name")
@ElementCollection(fetch = FetchType.EAGER)
@CollectionTable(name = "composers")
@OnDelete(action = OnDeleteAction.CASCADE)
@JoinColumn(name = "composer_id")
private Set<String> composer;
@Column(name = "author_of_words_name")
@ElementCollection(fetch = FetchType.EAGER)
@CollectionTable(name = "author_of_words")
@OnDelete(action = OnDeleteAction.CASCADE)
@JoinColumn(name = "authorOfWords_id")
private Set<String> authorOfWords;
@Column(name = "song_artist")
private String songArtist;
@Column(name = "song_timing")
private int songTiming;
@ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH})
@JoinColumn(name = "user_id_key")
private User user;
@Column(name = "rate_value")
@ElementCollection(fetch = FetchType.EAGER)
@CollectionTable(name = "rating")
@MapKeyColumn(name = "login")
@OnDelete(action = OnDeleteAction.CASCADE)
@JoinColumn
private final Map<String, Integer> rating = new HashMap<>();
@Column
@ElementCollection(fetch = FetchType.EAGER)
@CollectionTable(name = "comment")
@MapKeyColumn(name = "login")
@OnDelete(action = OnDeleteAction.CASCADE)
@JoinColumn
private final Map<String, String> comments = new HashMap<>();
}
I want to delete a Song, but not delete a User.我想删除一首歌曲,但不删除一个用户。
I tried deleting it like this:我试着像这样删除它:
Query query = session.createQuery("DELETE Song s WHERE s.user = :user AND s.songTitle = :songTitle");
query.setParameter("user", user);
query.setParameter("songTitle", songTitle);
query.executeUpdate()
But the error drops:但错误下降:
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".
I understand that the problem is due to the fact that in the spanning table users_songs
, which occurred due to the connection @OneToMany
.我知道问题是由于在生成表
users_songs
中,这是由于连接@OneToMany
而发生的。
I read a similar question in the STO and it says that you need to break the connection.我在 STO 中阅读了一个类似的问题,它说您需要断开连接。 how to delete the record from the join table in hibernate
如何从 hibernate 中的连接表中删除记录
I executed the following code:我执行了以下代码:
List<Song> collect = user.getSongs().stream().filter(s -> !s.getSongTitle().equals(songTitle)).collect(Collectors.toList());
user.setSongs(collect);
session.update(user);
Query query = session.createQuery("DELETE Song s WHERE s.songTitle = :songTitle");
query.setParameter("songTitle", songTitle);
query.executeUpdate();
This code works, but I don't think it's quite right.这段代码有效,但我认为它不太正确。 Now the question.
现在的问题。 How do I delete a Song from a user?
如何删除用户的歌曲? With the condition that the song should not cascade to delete the user.
条件是歌曲不应该级联删除用户。
Please help me solve this issue correctly.请帮我正确解决这个问题。 I'd really appreciate it.
我真的很感激。
You can specify ON DELETE CASCADE
for the foreign key constraint fka7me64vk6jtx81wt2ggbvm6ur
on the table users_songs
like below:您可以为表
users_songs
上的外键约束fka7me64vk6jtx81wt2ggbvm6ur
指定ON DELETE CASCADE
,如下所示:
@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<>();
and after database schema regeneration your initial query should work as expected.并且在数据库模式重新生成后,您的初始查询应该按预期工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.