10

我有一个实体 [项目],其中包含一组其他实体 [问题]。

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

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

当我这样做时session.delete(project),它会抛出一个异常,说project_idcant be null,但是如果我删除not-null对该字段的约束,则删除效果很好。

任何人都知道如何解决这个问题?

4

3 回答 3

11

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

然而,这段代码

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();

不会从数据库中删除 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();

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

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

编辑:

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

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

not-null="true"

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

于 2008-10-14T01:13:20.847 回答
0

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

于 2008-10-14T00:20:56.957 回答
-2

删除首先发生在项目上并级联到问题,但项目删除包括问题中 project_id 的置空(为了参照完整性。您在删除问题对象时没有遇到异常,但是因为cascade 正在尝试使问题中的 FK 为空。

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

于 2008-10-13T23:49:39.767 回答