当前位置: 首页 > 知识库问答 >
问题:

无法删除父实体,因为在双向映射情况下有子引用

施彦
2023-03-14
  1. 父级不拥有colum,因此映射由“mappedby”配置
  2. 子项有一个复合键,其中一个列通过其ID链接到父项
  3. 配置由JPA注释完成

当hibernate执行它的查询时,它不能发现有一些子级对试图删除的记录有外键约束,所以它希望执行“父级先删除”,然后移动到“子级”。

起因是:

    null
  • 可选=false
  • name=表列的名称
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import java.util.Objects;
import java.util.Set;

@Entity
public class Parent {
    @Id
    @Column
    private long id;

    @Column
    private String name;

    @OneToMany(mappedBy = "parent",
            fetch = FetchType.EAGER,
            cascade = CascadeType.ALL,
            orphanRemoval = true)
    private Set<Child> children;

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Set<Child> getChildren() {
        return children;
    }

    public void setChildren(Set<Child> children) {
        this.children = children;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Parent parent = (Parent) o;
        return id == parent.id;
    }

    @Override
    public int hashCode() {
        return Objects.hash(id);
    }
}
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.IdClass;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import java.util.Objects;

@Entity
@IdClass(ChildIdentifier.class)
public class Child {
    @Id
    @Column
    private long id;

    @Column
    private String name;

    @Id
    @JoinColumn(nullable = false,
            name ="parent_id",
            referencedColumnName = "id")
    @ManyToOne(optional = false)
    private Parent parent;

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Parent getParent() {
        return parent;
    }

    public void setParent(Parent parent) {
        this.parent = parent;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Child child = (Child) o;
        return id == child.id &&
                Objects.equals(parent, child.parent);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, parent);
    }
}
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import java.io.Serializable;
import java.util.Objects;

public class ChildIdentifier implements Serializable {
    @Id
    @Column
    private long id;
    @JoinColumn(nullable = false,
            name ="parent_id",
            referencedColumnName = "id")
    @ManyToOne(optional = false)
    private Parent parent;

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        ChildIdentifier that = (ChildIdentifier) o;
        return id == that.id &&
                Objects.equals(parent, that.parent);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, parent);
    }

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public Parent getParent() {
        return parent;
    }

    public void setParent(Parent parent) {
        this.parent = parent;
    }
}

共有1个答案

甄胡非
2023-03-14

我想通了问题。删除不是通过实体管理器的remove功能完成的。

执行delete操作的存储库由@Query注释实现(示例@Query(“delete from parent where id=:id”))。我还没有完全理解这种行为背后的原因,但JPQL没有导致正确的订单删除。

要解决此问题:

    null
 类似资料:
  • 是否可以从索引中删除单个映射类型而不删除整个索引?https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-delete-mapping.html说这已经不可能了,但我觉得这很难相信。有人能解释为什么删除了该功能吗?似乎是基本的东西。 我有一个具有两个映射的索引。我希望能够删除一种映射类型(以及该类型的所有文档)

  • 删除父实体时,我还想删除关联的子实体(从数据库中)。我试图在删除时使用级联,如下所示,但我一定做错了什么。 当对父实体对象调用删除时,我收到错误消息:“该实体仍在数据库的其他地方引用”。我可以确认该实体在数据库的其他地方引用的唯一地方是在下面的两个表中(如果我手动从数据库中删除子行,对父实体对象的删除调用工作正常)。在过去的9个小时里,我一直在阅读实体对象并尝试不同的东西。我做错了什么? 这是我的

  • 我正在尝试删除一个父/子自连接实体,但无法这样做,这里是我的映射

  • 任何关于primeNg(像Material这样的第三方库)如何在组件中实现双向绑定的想法,因为每当我创建一个可重用组件时,我必须使用属性绑定向子组件提供值,并使用@input在子组件中接收它,如果我想要从子组件中获得任何数据,我使用@output在父组件中接收它。但是在Primen可重用组件中可以看到,它们可以直接使用双向绑定来提供和接收值。 https://www.primefaces.org/

  • 我正在使用实体框架映射一些表,但除非我声明一些列作为主键,否则我无法这样做。 这里的问题是,数据库中的表没有主键,并且有数百万行。我没有创建新Id列的权限。 Obs:如果我将属性添加到诸如

  • 我的实体。ValidationStep与documentDetail有一对一的关系,documentDetail与documentValidations有一个完全的关系 我的删除查询 父ValidationStep被删除,但是docDetail和documentValidations仍然在数据库中。