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;
}
添加回答
舉報