繁体   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