如何在使用Hibernate删除父项时删除所有子行?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在使用Hibernate删除父项时删除所有子行?相关的知识,希望对你有一定的参考价值。

我有2张桌子。

// Accounts
@OneToMany(mappedBy="accounts", cascade=CascadeType.ALL)
@Cascade(org.hibernate.annotations.CascadeType.ALL)
private Set<Mails> mails;

// Mails
@ManyToOne(cascade=CascadeType.ALL)
@JoinColumn(name="user_id" , referencedColumnName="id", insertable=false, updatable=false)
private Accounts accounts;

如何在删除父行时组织删除所有子行?我试图为CascadeType.DELETE_ORPHAN表设置Accounts,但是如果存在子行,我就无法删除父行。

答案

问题可能是关系定义在错误的方向。假设你有一个与account表有一对多关系的mail表,如果你在account上定义关系来引用mail,你将最终无法从account中删除记录,直到它关联mail行。正确的方法是在mail上创建外键以引用account

使用ON DELETE CASCADE,您告诉mysql它应该删除一行(其表具有外键),如果其父(由键引用)被删除。定义允许此操作,因为在这种情况下,已删除的记录具有对它的引用。相反,如果记录具有指向其中的其他记录的引用,则不允许删除。

另一答案

您在两个实体中使用cascade = CascadeType.ALL。尝试仅在父母那里使用它。这应该工作

//Accounts
@OneToMany(mappedBy="accounts", cascade=CascadeType.ALL,orphanRemoval=true)    
private Set<Mails> mails;

//Mails
 @ManyToOne
 @JoinColumn(name="user_id" , referencedColumnName="id" , nullable=false)
 private Accounts accounts;
另一答案

“mappedBy”属性表示另一方拥有该关系,因此在您的情况下,Mails拥有的关系可能不是您想要的。

JPA Cascades只从一个方向开始工作,来自关系的所有者。

因此,如果您希望在删除帐户时删除邮件,则需要切换关系的所有者:

//Accounts
@OneToMany(cascade=CascadeType.ALL)
private Set<Mails> mails;

//Mails
@ManyToOne(mappedBy="mails")
@JoinColumn(name="user_id" , referencedColumnName="id", insertable=false, updatable=false)
private Accounts accounts;

以上是关于如何在使用Hibernate删除父项时删除所有子行?的主要内容,如果未能解决你的问题,请参考以下文章

JPA / Hibernate - 删除子项删除父项(从同一个表)

Hibernate:无法添加或更新子行:外键约束失败

检索项目的父项时出错:找不到资源 [重复]

查询父项时如何获取猫鼬子文档数组中的值的聚合总和?

MySql 触发器删除同一张表中的子记录

如何解决处理深度技术Win10系统删除注册表项时出错问题