在我的Play应用程序中使用Ebean / JPA,如何删除OneToOne关系中的对象?

时间:2012-08-23 13:45:29

标签: 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 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执行DML bindLog []错误[不能   删除或更新父行:外键约束失败   (databasenamea,CONSTRAINT fk_a_payme_4外键(b_id)   参考bid))]]

它基本上归结为我正在尝试删除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?

提前谢谢!

编辑:目前为止最好的想法:将a-b关系的所有权移至b。

2 个答案:

答案 0 :(得分:2)

尝试使用

class A{

   ......

   @JoinColumn(nullable=true)
   private B b;

   .......
}

有关详细信息,请参阅此问题What is the difference between @ManyToOne(optional=false) vs. @Column(nullable=false)

答案 1 :(得分:-1)

我遇到了@johny回答的一些问题。试试这个。

@JoinColumn(name = "b_id", nullable = false)