[英]Hibernate Cascaded update on non primary key column
我有兩個表格,這樣的結構。
1)Obj表 -
2)subobj表
我的方案是我有is_deleted列,在刪除時我不想刪除記錄而是我想將is_deleted設置為true並更新所需的依賴項。
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=2
的subobj
記錄時,該記錄的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.