2008-10-13 148 views
9

我有一个实体[Project]包含其他实体集合[Questions]。休眠删除级联

我制订与“​​全删除,孤儿”级联属性的关系。

在我的DB的关系映射与问题表PROJECT_ID(FK)领域。此字段不能为空,因为我不想要没有项目的问题。

当我使用Session.delete(项目),它抛出一个异常说PROJECT_ID不能为null,但如果我删除非空约束到该字段,删除工作良好。

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

+0

您可能应该显示映射的相关部分。我一直使用all-delete-orphan来处理非空外键,并且从来没有遇到任何问题。 – 2008-10-14 04:07:49

回答

-2

删除发生在项目上,并且级联到问题上,但是项目删除在问题中包含了对project_id的空值(用于参照完整性)。在删除Question对象时没有得到异常,但是因为级联正试图为null FK的问题(S)。

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

+0

这并不能解决任何问题 – 2008-10-14 00:01:31

0

一种策略是使其尽快标志着数据库上删除级联的外键,例如NHibernate告诉数据库中删除一个项目,数据库本身会级联删除。然后你必须告诉NHibernate数据库本身进行级联删除。从documentation

+0

是否可以用nhibernate 1.2? – 2008-10-14 00:23:35

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

不会从数据库中删除℃;它只会删除链接到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(); 

现在,在我们的情况下,一个孩子不能没有父母就真的存在。所以如果我们从集合中删除一个孩子,我们确实希望它被删除。为此,我们必须使用cascade =“all-delete-orphan”。

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

编辑:

至于逆东西,我相信这不仅决定是如何生成的SQL,看到这个doc获取更多信息。

有一点要注意的是,你有没有在你的Hibernate配置的多对一的关系得到了

not-null="true" 

+0

对不起。这确实有用,但我不明白为什么。从文档中可以看到,当您映射双向关联时(这不是我的情况),会使用反向真实,反正添加它可以很好地工作。谢谢。如果你编辑解释为什么inverse = true的作品,我会接受你的回答 – 2008-10-14 13:46:09