我有以下课程:
import play.db.ebean.Model;
import javax.persistence.*;
@Entity
public class A extends Model {
@Id
private int id;
/* Other irrelevant properties */
@OneToOne(cascade = CascadeType.ALL, optional = true)
private B b;
}
import play.db.ebean.Model;
import javax.persistence.*;
@Entity
public class B extends Model {
@Id
private int id;
/* Other irrelevant properties */
@OneToOne(mappedBy = "b")
private A a;
@OneToOne(cascade = CascadeType.ALL, optional = false)
private C c;
}
import play.db.ebean.Model;
import javax.persistence.*;
@Entity
public class C extends Model {
@Id
private int id;
/* Other irrelevant properties */
@OneToOne(mappedBy = "c")
private B B;
}
在数据库中,它看起来像这样:
Table a
Columns id, ... (other irrelevant columns), b_id
Table b
Columns id, ...(other irrelevant columns), c_id
Table c
Columns id, ...(other irrelevant columns)
现在在一个控制器方法中(对于那些熟悉 Play 的人)我有一个对象 A,并且想从数据库中删除它的属性“b”。这也应该级联到 c,因此 c 也被删除。这是我目前的做法:
B b = a.getB();
b.delete();
但是,这会引发异常:
[PersistenceException: ERROR execution DML bindLog[] error[Cannot delete or update a parent row: a foreign key constraint failed (
databasename
.a
, CONSTRAINTfk_a_payme_4
FOREIGN KEY (b_id
) REFERENCESb
(id
))]]
它基本上归结为我试图删除 b 的事实,而 a 在 b_id 列中仍然持有对 b 的外键引用,所以我应该首先将该引用设置为 null。
在 Java 中,这转换为:
B b = a.getB();
a.setB(null);
a.update();
b.delete();
这确实将对象 a 中对 b 的引用设置为 null 并正确删除 b 对象,但 c 不会从数据库中删除。(为什么?我虽然级联属性会处理这个问题)我发现解决这个问题的唯一方法是显式删除 c ,就像这样:
B b = a.getB();
C c = b.getC();
b.setC(null);
b.update();
c.delete();
a.setB(null);
a.update();
b.delete();
不过我对此不是很满意,因为这已经是删除数据库中两行的 8 行代码了,如果这张图中有更多的关系会更多。
至于我的问题:
如何从 a 中删除 b,以便首先自动删除从 a 到 b 的引用,以及如何确保在删除 b 时也删除 c?
先感谢您!
编辑:迄今为止最好的想法:将ab关系的所有权移至b。