Java 在我的Play应用程序中使用Ebean/JPA,如何删除OneToOne关系中的对象?
我有以下课程:Java 在我的Play应用程序中使用Ebean/JPA,如何删除OneToOne关系中的对象?,java,jpa-2.0,playframework-2.0,cascade,ebean,Java,Jpa 2.0,Playframework 2.0,Cascade,Ebean,我有以下课程: 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 A extends Model {
@Id
private int id;
/* Other irrelevant properties */
@OneToOne(cascade = CascadeType.ALL, optional = true)
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)
B b = a.getB();
C c = b.getC();
b.setC(null);
b.update();
c.delete();
a.setB(null);
a.update();
b.delete();
现在在一个控制器方法中(对于熟悉Play的人),我有一个A的对象,并且想从数据库中删除它的属性“b”。这也应该级联到c,所以c也会被删除。
这是我目前的做法:
B b = a.getB();
b.delete();
但这会引发一个异常:
[PersistenceException:执行DML bindLog时出错[]错误[无法执行]
删除或更新父行:外键约束失败
(databasename
a
,CONSTRAINTfk\u a\u payme\u 4
外键(b\u id
)
参考资料b
(id
)]]
基本上可以归结为这样一个事实:我试图删除b,而a仍然在b_id列中保存对b的外键引用,所以我应该首先将该引用设置为null
在Java中,这转化为:
B b = a.getB();
a.setB(null);
a.update();
b.delete();
这会将对象a中对b的引用设置为null,并正确删除b对象,但不会从数据库中删除c。(为什么?我以为cascade酒店会处理这个问题)
我发现解决这个问题的唯一方法是显式删除c,如下所示:
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)
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?
提前谢谢你
编辑:到目前为止的最佳想法:将a-b关系的所有权移动到b。尝试使用
class A{
......
@JoinColumn(nullable=true)
private B b;
.......
}
有关更多信息,请参阅此问题。我遇到了@johny answer的一些问题。试试这个
@JoinColumn(name = "b_id", nullable = false)
这与
@OneToOne(optional=true)
有何不同?谢谢你的链接,我又学到了一些新东西。不过,我不认为这能解决我的问题,当我看数据库设计时,它说表“a”中的列“b_id”是可空的,所以这不会改变任何东西,对吗?所以级联规则在Ebean中根本不起作用?好吧,至少我可以开始寻找更好的解决方案了。谢谢,我接受了这一点。级联规则是有效的,它不在生成的DDL中。您必须手动编辑生成的DDL。所有生成的DDL都在/conf/evolutions/中。您可以使用Hibernate作为替代方法。