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
,CONSTRAINT
fk\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作为替代方法。