错误:对表“ tablename”的更新或删除违反了外键约束

Mer*_*erv 10 postgresql spring-data-jpa spring-boot

我正在尝试删除家长学生或家长课程,但出现此错误:

由以下原因引起:org.postgresql.util.PSQLException:错误:表“ student”上的更新或删除违反了表“注册”上的外键约束“ fkeyvuofq5vwdylcf78jar3mxol”

RegistrationId类是Registration类中使用的组合键。我正在使用Spring data jpa和spring boot。

我究竟做错了什么?我知道,当删除父级时,放置cascadetype.all还应该删除子级,但是这给了我一个错误。

@Embeddable
public class RegistrationId implements Serializable {

  @JsonIgnoreProperties("notifications")
  @OneToOne(cascade=CascadeType.ALL)
  @JoinColumn(name = "student_pcn", referencedColumnName="pcn")
  private Student student;

  @JsonIgnoreProperties({"teachers", "states", "reviews"})
  @OneToOne(cascade=CascadeType.ALL)
  @JoinColumn(name = "course_code", referencedColumnName="code")
  private Course course;
Run Code Online (Sandbox Code Playgroud)


注册班

@Entity(name = "Registration")
@Table(name = "registration")
public class Registration {

@EmbeddedId
private RegistrationId id;
Run Code Online (Sandbox Code Playgroud)

Mer*_*erv 9

我通过使用休眠@OnDelete注释使其工作。JPA.persistence CascadeTypes如何无法正常工作。对于我选择的任何一个,它们都没有作用。

就像下面一样。现在,我可以删除父级“学生”或父级“课程”,并且所有子级(注册)也会随之删除。

@Embeddable
public class RegistrationId implements Serializable {

    @JsonIgnoreProperties("notifications")
    @OnDelete(action = OnDeleteAction.CASCADE)
    @OneToOne
    @JoinColumn(name = "student_pcn", referencedColumnName="pcn")
    private Student student;

    @JsonIgnoreProperties({"teachers", "states", "reviews"})
    @OnDelete(action = OnDeleteAction.CASCADE)
    @OneToOne
    @JoinColumn(name = "course_code", referencedColumnName="code")
    private Course course;
Run Code Online (Sandbox Code Playgroud)


Jos*_*pen 6

外键保证条目将存在于另一个表中。这是确保数据完整性的一种方法。SQL 永远不会允许您删除此条目,同时它仍在另一个表中删除。(1)这让你知道如果删除这个必需的东西你会犯一个严重的错误,或者(2)你想进行级联删除,这样不仅这个条目被删除,而且假设的内容也被删除在另一个表中引用它。有关级联删除的信息可以在这里找到并且编写起来相当容易(https://www.techonthenet.com/sql_server/foreign_keys/foreign_delete.php)。如果这两种描述都不适合您,请首先评估您的外键关系存在的原因,因为它可能不应该存在。

  • 感谢您的回答。基本上我想要的是在添加新注册时确保数据完整性(学生和课程必须存在),这就是我使用这些外键的原因。而且当我删除父级时,也可以通过放置cascadetype.all,它应该将所有子级都带走。这就是我想要的。 (2认同)

Mos*_*rad 5

使用关系数据库时,您将设置具有这些实体之间关系的实体。

您得到的错误意味着:

您试图删除一条记录,该记录的主键正在另一个表中用作外键,因此无法删除它。

为了删除该记录,请首先使用外键删除该记录,然后再删除要删除的原始记录。

  • 感谢您的回答。你是对的。我可以那样做。但这似乎是一种解决方法。因为通过放置注释cascade = cascadeType.all,当父级被删除时不应该删除子级吗?这基本上就是我想要它做的。删除此父级驻留在其他表中的所有子级。 (2认同)