亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Spring JPA OneToOne FK 作為 PK Cascade.Remove

Spring JPA OneToOne FK 作為 PK Cascade.Remove

瀟湘沐 2022-05-12 15:36:24
我有兩張桌子,b并且a:它們具有一對一的雙向關系a有一個外鍵來b定義這種關系這個外鍵也被認為是a, 和 JPA的主鍵@ID我想要一個級聯刪除,刪除相關的b何時a被刪除在 MySQL 中,a'sb_id是NOT NULL問題是當我A使用 JPA 存儲庫刪除我的對象時,我會ConstraintViolationException在其外鍵上得到一個。我希望a和b行都被刪除(巧妙地從a's 開始)。知道我想保留,我怎么能解決這個問題:我的數據庫架構相同a從到的級聯刪除bidb是 JPA@Id的aCREATE TABLE `b` (  `dbid` int(11) NOT NULL AUTO_INCREMENT,  PRIMARY KEY (`dbid`),);CREATE TABLE `a` (  `b_id` int(11) NOT NULL,  KEY `b_fk` (`b_id`),  CONSTRAINT `b_fk` FOREIGN KEY (`b_id`) REFERENCES `b` (`dbid`),);@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)    @PrimaryKeyJoinColumn    private B b;}@Entity@Table(name = "b")public class B {    @Id    @GeneratedValue(strategy= GenerationType.IDENTITY)    @Column(name = "dbid")    private Integer id;    @OneToOne(mappedBy = "b")    private A a;}[編輯] 在回答評論和重新閱讀我的問題的所有討論之后,這些提案orphanRemoval確實在范圍和工作中。
查看完整描述

3 回答

?
鳳凰求蠱

TA貢獻1825條經驗 獲得超4個贊

如果您想刪除 的對象B,只要關聯的對象A被刪除(這是您的愿望清單的第四點:

我想要一個級聯刪除,刪除相關的b何時a被刪除

那么您需要將映射更改A為:

@OneToOne(cascade = CascadeType.REMOVE, orphanRemoval = true)
@PrimaryKeyJoinColumn
private B b;


查看完整回答
反對 回復 2022-05-12
?
holdtom

TA貢獻1805條經驗 獲得超10個贊

就您實現的 MySQL 方面而言,表 B 中的記錄對表 A 中的任何記錄都沒有“知識”。在數據庫中,關系是單向的

存在本機級聯功能以防止外鍵錯誤,通過告訴數據庫在刪除記錄時要做什么會使外鍵無處指向。刪除表 A 記錄不會導致任何表 B 記錄中的外鍵錯誤,因此不會觸發任何本機級聯功能

重申;您不能保持模式相同,并且從ato級聯刪除b,因為您實際上沒有從ato級聯刪除b

您還在評論中提到,一些表 B 記錄可以存在而沒有表 A 記錄,而表 A 記錄不在原始問題中

要獲得您描述的表 B 記錄的自動刪除,您有幾個關于數據庫的選項:

  1. 交換關系- 刪除當前外鍵并在表 B 中添加一個可以為空的外鍵列,該列引用表 A 的主鍵。然后您可以在此外鍵上進行級聯刪除。對于不“屬于”表 A 記錄的表 B 記錄,保持新列為空。您還可以向此列添加唯一索引以確保一對一關系

  2. 添加數據庫觸發器- 刪除表 A 記錄時,添加刪除引用的表 B 記錄的數據庫觸發器

  3. 添加一個 DB 過程- 添加一個過程,刪除表 A 記錄,然后依次刪除引用的表 B 記錄,可能在事務中。繼續前進,僅使用該過程刪除表 A 記錄

  4. 不要在 DB 層面解決問題- 與選項 3 基本相同,但將過程邏輯從 DB 層移到應用程序邏輯中

JPA 中可能有一些東西可以開箱即用地解決您的困境,但在幕后它將執行上述操作之一(不是選項 1,可能是選項 4)


查看完整回答
反對 回復 2022-05-12
?
白板的微信

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;

}


查看完整回答
反對 回復 2022-05-12
  • 3 回答
  • 0 關注
  • 144 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號