我有两个表格,这样的结构.
>表格:
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 = 2的subobj记录时,该记录的is_deleted将设置为true,然后其他具有parent_subobj = 2的记录将被“删除”.这将级联更新字段is_deleted而不删除任何记录.但仔细考虑这里循环的可能性:如果你有一个id = 2的记录; parent_subobj = 3然后是另一个id = 3的记录; parent_subobj = 2你有一个无限循环.您可以通过仔细管理parent_subobj的分配或以其他方式使用检查循环的recursive CTE来避免这种情况.