我有一个用户。该用户有一份文件。该文件有几个条目。如果我删除一个文档,那么我想保留子条目,这将是孤儿,用于调试目的。使用底部描述的类,当我删除一个Document时,我得到一个外键错误:
无法删除或更新父行:外键约束失败 (
relation
。entry
,CONSTRAINTFK4001852ED0B1AFE
FOREIGN KEY (document_id
)参考document
(id
))
我正在使用一个基于模型创建表的框架。使用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;
}
答案 0 :(得分:2)
默认情况下,JPA不会对@ManyToOne
和Document
之间定义的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)
经过更多测试后,我发现如果Document
和Entry
之间没有双向关系,那么数据库中就不会添加任何外键,从而使删除子项成为子项。如果我添加了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;
}