删除对象但是将子项保留为孤立而没有“外键约束失败”错误?

时间:2013-07-17 08:26:53

标签: hibernate jpa foreign-keys cascade

我有一个用户。该用户有一份文件。该文件有几个条目。如果我删除一个文档,那么我想保留子条目,这将是孤儿,用于调试目的。使用底部描述的类,当我删除一个Document时,我得到一个外键错误:

  

无法删除或更新父行:外键约束失败   (relationentry,CONSTRAINT FK4001852ED0B1AFE FOREIGN KEY   (document_id)参考documentid))

我正在使用一个基于模型创建表的框架。使用cascade = CascadeType.REMOVE可以使它工作,但我不想删除子项。我应该使用特殊的CascadeType吗?

用户

@Entity
public class User {
    public String name;

    @OneToOne(mappedBy = "user", cascade = CascadeType.ALL)
    public Document document;
}

文档

@Entity
public class Document {
    public String title;

    @OneToOne
    public User user;

    @OneToMany(mappedBy = "document")
    public List<Entry> entries;
}

条目

@Entity
public class Entry {
    public String data;

    @ManyToOne
    public Document document;
}

2 个答案:

答案 0 :(得分:2)

默认情况下,JPA不会对@ManyToOneDocument之间定义的Entry关系等关系进行级联操作。由于映射中没有定义级联类型,因此级联删除最有可能由外键约束指定的数据库执行。

我怀疑您收到的错误来自数据库。在删除外键约束中的父项时,尝试更改在数据库中执行的级联操作。许多数据库允许您将外键设置为null。以下是Oracle的示例:

CONSTRAINT fk_column
     FOREIGN KEY (column1, column2, ... column_n)
     REFERENCES parent_table (column1, column2, ... column_n)
     ON DELETE SET NULL 

执行删除后,执行刷新以将持久性上下文与数据库重新对齐非常重要。

答案 1 :(得分:0)

经过更多测试后,我发现如果DocumentEntry之间没有双向关系,那么数据库中就不会添加任何外键,从而使删除子项成为子项。如果我添加了CascadeType.REMOVE,那么它也会删除孩子并且不会留下任何孤儿。但是,这会在数据库中创建一个新表document_entry

更新文件

@Entity
public class Document {
    public String title;

    @OneToOne
    public User user;

    @OneToMany
    public List<Entry> entries;
}

更新条目

@Entity
public class Entry {
    public String data;
}