java 使用 Hibernate 删除父行时如何删除所有子行?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17077499/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to delete all child rows when parent is deleted using Hibernate?
提问by Eugene Mironenko
I have 2 tables.
我有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;
How can I organize deleting all child rows when the parent row will be deleted? I have tried to set CascadeType.DELETE_ORPHAN
for the Accounts
table, but with that I can't delete parent rows if a child row exists.
当父行将被删除时,如何组织删除所有子行?我试图CascadeType.DELETE_ORPHAN
为Accounts
表设置,但是如果存在子行,我无法删除父行。
回答by marekful
The problem probably is that the relation is defined in the wrong direction. Presuming that you have an account
table with one-to-many relation to a mail
table, you will end up not being able to delete a record from account
until it has associated mail
rows if you define the relation on account
to reference mail
. The correct way is to create the foreign key on mail
to reference account
.
问题可能是关系的定义方向错误。假设您有一个account
与表具有一对多关系的mail
表,如果您将关系定义为引用,您将最终无法从中删除记录,account
直到它具有关联的mail
行。正确的方法是在引用上创建外键。account
mail
mail
account
With ON DELETE CASCADE
, you tell MySQL that it should delete a row (whose table has the foreign key) ifits parent (referenced by the key) is deleted. This operation is allowed by definition because in such a case the deleted record has references to it. In contrast, a deletion is not allowed if a record has references pointing to other records from it.
使用ON DELETE CASCADE
,你告诉 MySQL如果它的父行(由键引用)被删除,它应该删除一行(其表有外键)。根据定义,此操作是允许的,因为在这种情况下,已删除的记录具有对它的引用。相反,如果一个记录有指向其他记录的引用删除不允许从它。
回答by srikanth yaradla
You are using cascade=CascadeType.ALL in both entities. Try using that only at parent. This should work
您在两个实体中都使用了 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;
回答by samlewis
The "mappedBy" property indicates that the other side owns the relationship, so in your case Mails owns the relationship which is probably not what you want.
“mappedBy”属性表示另一方拥有该关系,因此在您的情况下,Mails 拥有可能不是您想要的关系。
JPA Cascades only work in one direction, from the owner of the relationship.
JPA Cascades 只在一个方向上工作,来自关系的所有者。
So if you want Mails to be deleted when deleting an Account, you need to switch the owner of the relationship:
所以如果你想在删除一个Account时删除Mails,你需要切换关系的所有者:
//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;