2017-06-15 255 views
2

我试图删除父学生或家长当然,我得到这个错误:错误:更新或删除表“表名”违反外键约束

引起:org.postgresql.util.PSQLException :错误:表“学生”上的更新或删除违反了表“注册”上的外键约束“fkeyvuofq5vwdylcf78jar3mxol”

RegistrationId类是注册类中使用的组合键。我使用Spring数据jpa和spring引导。

我在做什么错?我知道把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; 

回答

2

我通过使用hibernate @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; 
0

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

+0

感谢您的回答。基本上我想要的是在添加新注册(学生和课程必须存在)时确保数据完整性,这就是为什么我使用这些外键。但是,通过放置cascadetype.all,当我删除父母时,它应该把所有的孩子带走。这就是我想要的。 – Merv

2

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

你得到这意味着错误:

你试图删除一条记录,它的主键作为另一个表的外键功能,因此,你可以不删除它。

为了删除记录,首先用外键删除记录,然后删除要删除的原件。

+0

感谢您的回答。你是对的。我可以这样做。但它似乎是一种解决方法。因为通过放置注释cascade = cascadeType.all,当父项被删除时是否应该删除子项?这基本上是我想要它做的。删除该父母驻留在其他表中的所有子女。 – Merv

+0

这不是一个解决方法,那就是你的错误意味着什么。与级联有关。所有,是的,它假设删除关系中的另一个实体,而spring-data肯定会尝试,但是,由于其他外键没有这样做。为了实现你想要的,只需先删除保存外键的实体。 –

+0

如果这有帮助,我会欣赏一个投票和回答标记。谢谢。 @Merv –