在我的 Play 应用程序中使用 Ebean/JPA,如何删除 OneToOne 关系中的对象?
Posted
技术标签:
【中文标题】在我的 Play 应用程序中使用 Ebean/JPA,如何删除 OneToOne 关系中的对象?【英文标题】:Using Ebean/JPA in my Play application, how can I delete an object in a OneToOne relationship? 【发布时间】:2012-08-23 13:45:28 【问题描述】:我有以下课程:
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 删除或更新父行:外键约束失败 (
databasename
.a
, 约束fk_a_payme_4
外键 (b_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 不会从数据库中删除。 (为什么?我虽然级联属性会处理这个) 我发现解决此问题的唯一方法是也显式删除 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。
【问题讨论】:
【参考方案1】:尝试使用
class A
......
@JoinColumn(nullable=true)
private B b;
.......
有关更多信息,请参阅此问题What is the difference between @ManyToOne(optional=false) vs. @Column(nullable=false)。
【讨论】:
这与@OneToOne(optional = true)
有何不同?
感谢您的链接,我又学到了一些新东西。我看不出这如何解决我的问题,当我查看数据库设计时,它说表 'a' 中的列 'b_id' 可以为空,所以这不应该改变任何东西,对吧?
所以级联规则在 Ebean 中根本不起作用?好吧,至少我可以开始寻找更好的解决方案。谢谢,我已经接受了。
级联规则确实有效,但它不在生成的 DDL 中。您必须手动编辑生成的 DDL。所有生成的 DDL 都在 我在@johny 的回答中遇到了一些问题。试试这个。
@JoinColumn(name = "b_id", nullable = false)
【讨论】:
以上是关于在我的 Play 应用程序中使用 Ebean/JPA,如何删除 OneToOne 关系中的对象?的主要内容,如果未能解决你的问题,请参考以下文章
Google Play 服务在我的 Android 游戏中无法正常运行
Google Play Service 的 proguard 配置,在我的应用程序中还是在 lib 项目中?
在我的 Google Play 帐户中,应用登录私钥按钮已禁用
发布我的应用程序后,如何在我的 google play 控制台上更改应用程序内容描述?