簡體   English   中英

Hibernate Postgres 刪除自引用單向實體

[英]Hibernate Postgres Delete self referencing unidirectional entity

我將嘗試解釋我的問題:

我正在使用 Spring 啟動/休眠,父實體是

getter/setter 和其他字段被省略

public class BaseEntity {
    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

@Valid
@JsonManagedReference
@OneToMany(mappedBy = "contract", fetch = FetchType.EAGER, orphanRemoval = true, cascade = {CascadeType.MERGE, CascadeType.DETACH, CascadeType.PERSIST, CascadeType.REMOVE})
@OnDelete(action = OnDeleteAction.CASCADE)
private List<ChildEntity> myList = new ArrayList<>();

public void addChildEntityChildEntity list) {
    myList.add(list);
    list.setChildEntity(this);
}

public void removeChildEntity(ChildEntity entity) {
    myList.entity(entity);
    list.setChildEntity(null);
}
public List<ChildEntity> getChildEntitys(){
    return this.myList;
}


public class ChildEntity   {
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;


@Valid
@JsonBackReference
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "baseentity_id", referencedColumnName = "id",nullable = false)
@OnDelete(action = OnDeleteAction.CASCADE)
private BaseEntity baseEntity;


//here is the self reference in the child
@Nullable
@Valid
@ManyToOne(fetch = FetchType.EAGER, cascade={CascadeType.REMOVE, CascadeType.PERSIST, CascadeType.REFRESH})
@JoinColumn(name = "reference_child_id", referencedColumnName = "id")
@OnDelete(action = OnDeleteAction.CASCADE)
private ChildEntity referenceChildEntity;


public void addChildEntity(ChildEntity childEntity) {
    this.referenceChildEntity = childEntity;
    referenceChildEntity.setChildEntity(this);
}

public void removeChildEntity() {
    referenceChildEntity.setChildEntity(null);
    referenceChildEntity = null;
}

public void addToParentEntity(BaseEntity baseEntity) {
    baseEntity.addChildEntity(this);
    this.setChildEntity(baseEntity);
}

public void removeBaseEntity() {
    this.baseEntity.removeChildEntity(this);
    this.baseEntity = null;
}

這些是重要的實體:

但是,當我嘗試刪除 BaseEntity:並且與具有其他 ChildEntity 關系的 ChildEntity 存在關系時,我收到約束錯誤

Caused by: org.postgresql.util.PSQLException: ERROR: update or delete on table "base_entity" violates foreign key constraint "reference_child_id" on table "base_entity"
  Detail: Key (id)=() is still referenced from table "base_entity".
  Where: SQL statement "delete from base_entity where id = id.id"

這是來自 psql 的約束:

 CONSTRAINT_id_fkey FOREIGN KEY (reference_child_id)
        REFERENCES base_entity (id) MATCH SIMPLE
    

最后,刪除發生在 sql function 中,如下所示:

create or replace function delete_base_entity_by_id(
  base_id int
)
  returns void as
$BODY$
declare
  loop_base base_entity;
  loop_child child_entity;
begin
  for loop_base in (select * from base_entity where original_id = (select original_id from base_entity where id = base_id) order by start_date, id desc) loop
    for loop_child in (select * from child_entity where base_id = loop_base.id order by id desc) loop
      delete from child2 where child_id = loop_child.id;
      delete from child3 where child_id = loop_child.id;
      delete from child4 where child_id = loop_child.id;
      delete from child5 where loan_child_id = loop_child.id;
      delete from child6 where loan_child_id = loop_child.id;
      delete from child7 where child_id = loop_child.id;
      delete from child8 where child_id = loop_child.id;
      delete from child9 where id = loop_child.id;
    end loop;
    delete from base_entity where id = loop_base.id;
  end loop;
  delete from child_entity where id = loop_base.loan_id;
end
$BODY$
  language plpgsql;

我試圖在表上添加刪除級聯,但我嘗試使用 sql function 刪除的孩子有問題

 alter table child_entity
drop constraint id_fkey,
add constraint id_fkey
   foreign key (reference_child_id)
    REFERENCES child_entity (id)
   on delete cascade;

對此真的有任何想法和建議:

要解決此問題,您可以使用延遲外鍵約束。

alter table child_entity
drop constraint id_fkey,
add constraint id_fkey
   foreign key (reference_child_id)
    REFERENCES child_entity (id)
    deferrable initially deferred;

這將導致數據庫在事務提交時而不是在語句之后強制執行約束。

暫無
暫無

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

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