簡體   English   中英

讓Hibernate在保存時級聯,但不能刪除?

[英]Getting Hibernate to cascade on save, but not delete?

所以我的hibernate實現有問題。 當我嘗試刪除父類時,我在級聯層次結構深處的類上收到外鍵約束異常。 在我詳細介紹之前,我將首先描述類的關系,因為它與它們如何被保存和刪除有關。

在頂層,我有一個Customer類,其中包含一個DefaultMask對象列表。 這是主列表,因為這些默認掩碼由我的對象層次結構中的其他類使用,但始終來自此列表。 掩碼僅創建到此列表中並從此列表中刪除。

在層次結構的下面,我有一個Column類,它可以(可選)在其上設置DefaultMask。 更簡潔地描述這種關系;

客戶OWNS零到多個DefaultMasks。 客戶OWNS零到多列。 列可以有一個DefaultMask。

在我的應用程序中,當我嘗試刪除Customer時,異常來自Column類的外鍵約束到DefaultMask類,我相信問題是CascadeType的設置不正確。 我已經研究了這個問題並找到了一個名為mappedBy的屬性和使用Hibernate自己的CascadeType.SAVE_UPDATE的信息(為了防止Hibernate試圖刪除一個Column所持有的DefaultMask),但我承認我在這里有點迷失了使用一些直接指導。 類的相關代碼和實際的異常消息如下所示。

顧客:

@Entity
public class Customer {

@Id
private String id;
@OneToMany(cascade = CascadeType.ALL)
private List<DefaultMask> masks;
    //(Columns are held further down in hierarchy)

柱:

@Entity
@Table(name = "WarehouseColumn")
public class Column implements Comparable<Column> {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int hibernateID;
@OneToOne
private DefaultMask mask;

DefaultMask:

@Entity
public class DefaultMask implements Mask {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int hibernateID;
private String type;
private String mask;

異常消息:

org.hibernate.exception.ConstraintViolationException:不能刪除或更新父行,外鍵約束失敗( hibernateWarehouseColumn ,約束FK8BB153D994AD57D3外鍵( mask_hibernateID )參考文獻DefaultMaskhibernateID ))產生的原因:com.mysql.jdbc.exceptions。 jdbc4.MySQLIntegrityConstraintViolationException:不能刪除或更新父行,外鍵約束失敗( hibernateWarehouseColumn ,約束FK8BB153D994AD57D3外鍵( mask_hibernateID )引用DefaultMaskhibernateID ))

級聯與邏輯所有權的概念密切相關。

基本上,您需要選擇以下選項之一:

  • Customer邏輯上擁有其DefaultMask 在這種情況下,您希望在刪除Customer時刪除DefaultMask ,因此您需要使用CascadeType.ALL 由於Column引用了DefaultMask ,它可能也歸Customer所有,應該刪除

    它可以通過使用DefaultMaskColumn之間的雙向關系以及適當的級聯來實現,如下所示:

     @Entity public class DefaultMask implements Mask { @OneToOne(mappedBy = "mask", cascade = CascadeType.ALL) Column column; ... } 
  • DefaultMask是它們自己的實體, Customer只引用現有的DefaultMask 在這種情況下,您可能根本不需要使用級聯來實現此關系。

您正急於刪除一個客戶,該客戶會自動刪除其默認掩碼列表。 但是這些掩碼中的一個是由列引用的。 因此數據庫(以及Hibernate)拒絕執行刪除,因為它會使列處於不一致狀態:它將引用不再存在的默認掩碼。

所以你有幾個功能選擇:

  • 保持原樣:無法刪除客戶,因為其中一個掩碼仍由列引用
  • 刪除級聯:刪除客戶將刪除客戶但不刪除其掩碼。
  • 找到引用要刪除的用戶的任何默認掩碼的所有列,並刪除這些列。 然后,刪除用戶及其默認掩碼
  • 找到引用要刪除的用戶的任何默認掩碼的所有列,並將其掩碼fild設置為null。 然后,刪除用戶及其默認掩碼

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM