3 回答
TA贡献1825条经验 获得超4个赞
如果您想删除 的对象B
,只要关联的对象A
被删除(这是您的愿望清单的第四点:
我想要一个级联删除,删除相关的
b
何时a
被删除
那么您需要将映射更改A
为:
@OneToOne(cascade = CascadeType.REMOVE, orphanRemoval = true) @PrimaryKeyJoinColumn private B b;
TA贡献1805条经验 获得超10个赞
就您实现的 MySQL 方面而言,表 B 中的记录对表 A 中的任何记录都没有“知识”。在数据库中,关系是单向的
存在本机级联功能以防止外键错误,通过告诉数据库在删除记录时要做什么会使外键无处指向。删除表 A 记录不会导致任何表 B 记录中的外键错误,因此不会触发任何本机级联功能
重申;您不能保持模式相同,并且从a
to级联删除b
,因为您实际上没有从a
to级联删除b
您还在评论中提到,一些表 B 记录可以存在而没有表 A 记录,而表 A 记录不在原始问题中
要获得您描述的表 B 记录的自动删除,您有几个关于数据库的选项:
交换关系- 删除当前外键并在表 B 中添加一个可以为空的外键列,该列引用表 A 的主键。然后您可以在此外键上进行级联删除。对于不“属于”表 A 记录的表 B 记录,保持新列为空。您还可以向此列添加唯一索引以确保一对一关系
添加数据库触发器- 删除表 A 记录时,添加删除引用的表 B 记录的数据库触发器
添加一个 DB 过程- 添加一个过程,删除表 A 记录,然后依次删除引用的表 B 记录,可能在事务中。继续前进,仅使用该过程删除表 A 记录
不要在 DB 层面解决问题- 与选项 3 基本相同,但将过程逻辑从 DB 层移到应用程序逻辑中
JPA 中可能有一些东西可以开箱即用地解决您的困境,但在幕后它将执行上述操作之一(不是选项 1,可能是选项 4)
TA贡献1883条经验 获得超3个赞
为了实现您的要求,我对您的表格进行了如下调整:
CREATE TABLE b (
dbid INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY
);
CREATE TABLE a (
b_id int(11) NOT NULL PRIMARY KEY REFERENCES b(dbid) ON DELETE CASCADE
);
CASCADE DELETE没有添加到您的 DDL 中。
这将启用级联删除。要删除删除b记录,a我在课堂上做了以下更改A:
@Entity
@Table(name = "a")
public class A {
@Id
@Column(name = "b_id")
@GeneratedValue(generator = "gen")
@GenericGenerator(name = "gen", strategy = "foreign", parameters = @Parameter(name="property", value="b"))
private Integer bId;
@OneToOne(cascade = CascadeType.REMOVE, orphanRemoval = true)
@PrimaryKeyJoinColumn
private B b;
}
添加回答
举报