Java 休眠删除级联

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/199428/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 11:14:35  来源:igfitidea点击:

Hibernate Delete Cascade

javahibernatecascade

提问by Pablo Fernandez

I Have one entity [Project] that contains a collection of other entities [Questions].

我有一个实体 [Project],其中包含一组其他实体 [Questions]。

I have mapped the relation with a cascade attribute of "all-delete-orphan".

我已经用“all-delete-orphan”的级联属性映射了关系。

In my DB the relation is mapped with a project_id (FK) field on the questions table. this field cannot be null since I don't want a Question without a Project.

在我的数据库中,关系映射到问题表上的 project_id (FK) 字段。此字段不能为空,因为我不想要没有项目的问题。

When I do session.delete(project) it throws an exception saying that project_id cant be null, but if I remove the not-null constrain to that field, the deletion works nice.

当我执行 session.delete(project) 时,它会抛出一个异常,说明 project_id 不能为 null,但是如果我删除对该字段的非空约束,则删除效果很好。

Anyone knows how to solve this?

有谁知道如何解决这个问题?

回答by Steve Moyer

The delete is occurring on the Project first and cascading to the Question, but the Project delete includes a nulling of the project_id in the Questions (for referential integrity. You're not getting an exception on the deletion of the Question object, but because the cascade is trying to null the FK in the Question(s).

删除首先发生在项目上并级联到问题,但项目删除包括问题中 project_id 的清零(为了参照完整性。您不会在删除问题对象时获得异常,但因为级联试图将问题中的 FK 归零。

Looking at "Java Persistence with Hibernate", I think that what you really want a cascade type of delete or remove, not delete-orphans.

看看“ Java Persistence with Hibernate”,我认为你真正想要的是级联类型的删除或删除,而不是删除孤儿。

回答by yfeldblum

One strategy is to mark the foreign-key in the database with on-delete-cascade, so as soon as NHibernate tells the database to delete a project, the database itself will cascade the deletes. Then you have to tell NHibernate that the database itself does a cascade delete.

一种策略是用 on-delete-cascade 标记数据库中的外键,这样只要 NHibernate 告诉数据库删除一个项目,数据库本身就会级联删除。然后你必须告诉 NHibernate 数据库本身进行级联删除。

回答by abarax

Straight from the documentation. This explains your problem exactly i believe:

直接来自文档。这完全解释了你的问题,我相信:

However, this code

然而,这段代码

Parent p = (Parent) session.Load(typeof(Parent), pid);
// Get one child out of the set
IEnumerator childEnumerator = p.Children.GetEnumerator();
childEnumerator.MoveNext();
Child c = (Child) childEnumerator.Current;

p.Children.Remove(c);
c.Parent = null;
session.Flush();

will not remove c from the database; it will only remove the link to p (and cause a NOT NULL constraint violation, in this case). You need to explicitly Delete() the Child.

不会从数据库中删除 c;它只会删除到 p 的链接(并在这种情况下导致 NOT NULL 约束违规)。您需要显式删除()子项。

Parent p = (Parent) session.Load(typeof(Parent), pid);
// Get one child out of the set
IEnumerator childEnumerator = p.Children.GetEnumerator();
childEnumerator.MoveNext();
Child c = (Child) childEnumerator.Current;

p.Children.Remove(c);
session.Delete(c);
session.Flush();

Now, in our case, a Child can't really exist without its parent. So if we remove a Child from the collection, we really do want it to be deleted. For this, we must use cascade="all-delete-orphan".

现在,在我们的例子中,如果没有父级,子级就不能真正存在。因此,如果我们从集合中删除一个 Child,我们确实希望它被删除。为此,我们必须使用cascade="all-delete-orphan"。

<set name="Children" inverse="true" cascade="all-delete-orphan">
    <key column="parent_id"/>
    <one-to-many class="Child"/>
</set>

Edit:

编辑:

With regards to the inverse stuff, i believe this only determines how the sql is generated, see this docfor more info.

关于反向的东西,我相信这只会决定 sql 的生成方式,有关更多信息,请参阅此文档

One thing to note is, have you got

需要注意的一件事是,你有没有

not-null="true"

on the many-to-one relationship in your hibernate config?

休眠配置中的多对一关系?