【发布时间】:2022-10-07 19:27:20
【问题描述】:
我有以下课程:
public class Song {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(columnDefinition = "BIGINT(11) UNSIGNED")
private Long id;
private String name;
}
public class Playlist {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(columnDefinition = "BIGINT(11) UNSIGNED")
private Long id;
@ManyToMany
@CollectionTable(uniqueConstraints = @UniqueConstraint(columnNames = {"maps_id", "playlist_id"}))
private List<Map> songs = new ArrayList<>();
}
这个想法是能够创建多个“播放列表”,并且在每个列表中能够添加多个“歌曲”。同一“歌曲”可以在多个“播放列表”中。
我的问题是:如何删除“歌曲”并自动将其从包含它的所有播放列表中删除?
这个想法是使关系看起来像这样:
【问题讨论】:
-
目前尚不清楚您到底要什么 - 似乎您只是想要/需要关系表中 FK 上的 ON DELETE Cascade 集。您必须自己修改 DDL 脚本才能添加它。 JPA DDL 生成是一种开发人员工具,因此没有您的数据库提供的所有花里胡哨; JPA 的目标是 Java 持久性,而不是数据库访问。另请注意,像这样的 DB 直接更改是有效的,但在 JPA 模型之外。这意味着任何缓存的播放列表仍将引用现在删除的歌曲,直到它们也被刷新。
-
我试图不将关系放在我的“歌曲”表中并使其成为双向的。所以我想知道是否有任何参数或注释,例如 \@ManyToMany、\@OnDelete、\@JoinTable、\@JoinColumn 或任何其他,这对我有帮助,这样当我删除一首歌曲时,它们也会被删除在自动创建的名为“playlists_songs”的表中。如果不手动修改数据库结构,这可能吗?
-
没有。播放列表引用了 Song 并拥有关系,因此它无法从 Song 中知道播放列表引用了它。 JPA 希望您进行清理,否则您将收到 FK 约束错误。在 JPA 中解决这个问题的唯一方法是自己手动清除这些关系。要么使用 JPQL/native SQL 删除引用,要么通过读取所有引用歌曲的播放列表并将其从列表中删除。
-
数据库虽然有 ON DELETE 级联选项,但您可以在 FK 上设置,这似乎是您在图像中显示的内容。在数据库中的关系表/CollectionTable 上设置它会导致数据库在您删除引用的歌曲时自动清除那些 ManyToMany 行。然后,您需要在应用程序中处理陈旧的播放列表数据。
标签: java spring spring-boot hibernate jpa