【问题标题】:ERROR: update or delete on table "tablename" violates foreign key constraint错误:表“tablename”上的更新或删除违反外键约束
【发布时间】:2017-11-18 11:03:02
【问题描述】:

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

原因:org.postgresql.util.PSQLException:错误:更新或删除表“student”违反了表“registration”上的外键约束“fkeyvuofq5vwdylcf78jar3mxol”

RegistrationId 类是注册类中使用的复合键。我正在使用 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;


注册类

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

@EmbeddedId
private RegistrationId id;

【问题讨论】:

    标签: postgresql spring-boot spring-data-jpa


    【解决方案1】:

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

    您遇到的错误意味着:

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

    为了删除该记录,首先,删除带有外键的记录,然后删除您要删除的原始记录。

    【讨论】:

    • 感谢您的回答。是的,你是对的。我可以那样做。但这似乎是一种解决方法。因为通过放置注释cascade = cascadeType.all,在删除父级时不应该删除子级吗?这基本上就是我想要它做的。删除此父级驻留在其他表中的所有子级。
    • 这不是一种解决方法,这就是您的错误的含义。与 cascade.all 相关,是的,它应该删除关系中的另一个实体,并且 spring-data 肯定会尝试,但是,由于另一个外键它没有这样做。为了实现你想要的,只需先删除持有外键的实体。
    【解决方案2】:

    我通过使用休眠 @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;
    

    【讨论】:

      【解决方案3】:

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

      【讨论】:

      • 感谢您的回答。基本上我想要的是在添加新注册时确保数据完整性(学生和课程必须存在),这就是我使用这些外键的原因。但也可以在我删除父级时放置 cascadetype.all ,它应该带走所有的孩子。这就是我想要的。
      【解决方案4】:

      也试试这个方法。我用这种方法得到了答案,这只是一个要删除的测试。 注意级联!

      我的用户实体

      @Id
      @GeneratedValue(strategy = GenerationType.IDENTITY)
      private Long id;
      private String firstname;
      private String lastname;
      private String mobile;
      @Column(unique = true)
      private String email;
      private Long date;
      private LocalTime localiime;
      private LocalTime localiimeend;
      
      @ManyToOne(fetch = FetchType.LAZY,cascade = CascadeType.MERGE)
      @JoinColumn(foreignKey = @ForeignKey(name = "role_fk"))
      private Role role;
      

      角色实体

      @Id
      @GeneratedValue(strategy = GenerationType.IDENTITY)
      private Long id;
      private String name;
      private String description;
      
      @OneToMany(mappedBy = "role", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
      private List<MyUser> users;
      
      
      @ManyToOne (fetch = FetchType.LAZY,cascade = CascadeType.MERGE)
      @JoinColumn(foreignKey = @ForeignKey(name = "rolecat_fk"))
      private rolecat rolecat;
      

      角色实体

      @Id
      @GeneratedValue(strategy = GenerationType.IDENTITY)
      private Long id;
      private String name;
      
      @OneToMany(mappedBy = "rolecat", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
      private List<Role> roles;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-03-05
        • 1970-01-01
        • 1970-01-01
        • 2019-11-05
        • 2018-05-17
        • 2020-02-07
        • 1970-01-01
        相关资源
        最近更新 更多