簡體   English   中英

Hibernate級聯非主鍵列的更新

[英]Hibernate Cascaded update on non primary key column

我有兩個表格,這樣的結構。

  • 表:

1)Obj表 -

在此輸入圖像描述

2)subobj表

在此輸入圖像描述

我的方案是我有is_deleted列,在刪除時我不想刪除記錄而是我想將is_deleted設置為true並更新所需的依賴項。

  • 詳細的scenrios:

1)考慮,用戶正在從obj表中刪除一行,該表具有Id 1.now subobj表與obj_id相關聯的行1應將is_deleted設置為true。

2)subobj表包含一個自引用fk'parent_subobj ' 在這種情況下,我也想管理依賴項,例如,如果用戶正在刪除具有id 2的subobj記錄,那么對於具有“parent_subobj” 2的記錄, is_deleted應為true。

實體類:(使用JBOSS工具進行逆向工程)

Obj類: -

@Entity
@Table(name = "obj", schema = "public")
public class Obj implements java.io.Serializable
{
  private static final long serialVersionUID = 1L;

  @Id
  @Column(name = "id", unique = true, nullable = false)
  private int id;

  @Column(name = "obj_name", length = 100)
  private String objName;

  @Column(name = "is_deleted")
  private Boolean isDeleted;

  @OneToMany(fetch = FetchType.LAZY, mappedBy = "obj")
  private Set<Subobj> subobjs = new HashSet<Subobj>(0);
 // getters and setters
}

Subobj類: -

@Entity
@Table(name = "subobj", schema = "public")
public class Subobj implements java.io.Serializable
{
  @Id
  @Column(name = "id", unique = true, nullable = false)
  private int id;

  @ManyToOne(fetch = FetchType.LAZY)
  @JoinColumn(name = "obj_id")
  private Obj obj;

  @ManyToOne(fetch = FetchType.LAZY)
  @JoinColumn(name = "parent_subobj")
  private Subobj subobj;

  @Column(name = "subobj_name", length = 100)
  private String subobjName;

  @Column(name = "is_deleted")
  private Boolean isDeleted;

  @OneToMany(fetch = FetchType.LAZY, mappedBy = "subobj")
  private Set<Subobj> subobjs = new HashSet<Subobj>(0);
} 

所以可以在Hibernate中這樣做,或者我必須為級聯更新創建一個單獨的觸發器。 請提出所需的更改建議

Hibernate和PostgreSQL僅支持“標准”級聯操作,例如直接刪除記錄。 沒有您想要的那種“開箱即用”級聯更新。 您可以在java代碼中編寫您正在尋找的行為,但是將其作為兩個觸發器進行編寫更清晰,更不容易出錯(想象兩個Java應用程序訪問同一個表)。

obj上的觸發器功能和觸發器:

CREATE FUNCTION del_obj() RETURNS trigger AS $$
BEGIN
  UPDATE obj SET is_deleted = true WHERE id = OLD.id;
  UPDATE subobj SET is_deleted = true WHERE obj_id = OLD.id;
  RETURN NULL; -- fail the delete operation
END; $$ LANGUAGE plpgsql;

CREATE TRIGGER tr_del_obj
  BEFORE DELETE ON obj
  FOR EACH ROW EXECUTE PROCEDURE del_obj();

subobj上的觸發器功能和觸發器:

CREATE FUNCTION del_subobj() RETURNS trigger AS $$
BEGIN
  UPDATE subobj SET is_deleted = true WHERE id = OLD.id;
  DELETE FROM subobj WHERE parent_subobj = OLD.id;
  RETURN NULL; -- fail the delete operation
END; $$ LANGUAGE plpgsql;

CREATE TRIGGER tr_del_subobj
  BEFORE DELETE ON subobj
  FOR EACH ROW EXECUTE PROCEDURE del_subobj();

仔細查看最后一個觸發功能。 它更新正在刪除的記錄的is_deleted列(但不是真的),然后刪除引用它的記錄。 因此,當您“刪除” id=2subobj記錄時,該記錄的is_deleted將設置為true ,然后其他具有parent_subobj=2記錄將被“刪除”。 這將級聯更新字段is_deleted而不刪除任何記錄。 但仔細考慮這里循環的可能性:如果你有一個id=2;parent_subobj=3的記錄id=2;parent_subobj=3然后是另一個id=3;parent_subobj=2記錄id=3;parent_subobj=2你有一個無限循環。 您可以通過仔細管理parent_subobj的分配或以其他方式使用檢查循環的遞歸CTE來避免這種情況。

暫無
暫無

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

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