hibernate 休眠删除级联

z3yyvxxp  于 2022-11-14  发布在  其他
关注(0)|答案(4)|浏览(193)

我有一个实体[项目],其中包含其他实体[问题]的集合。
我已经将该关系Map为“all-ete-obalian”的级联属性。
在My DB中,关系与Questions表上的project_id(FK)字段Map。此字段不能为空,因为我不想要没有项目的问题。
当我执行session.delete(project)时,它抛出一个异常,说明project_id不能是null,但如果我删除该字段的not-null约束,删除工作就会正常进行。
有人知道怎么解决这个问题吗?

5w9g7ksd

5w9g7ksd1#

直接从文档中找到。这正好解释了你的问题,我相信:
但是,此代码

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-OBRAN”。

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

编辑:
至于相反的东西,我相信这只决定了SQL是如何生成的,有关更多信息,请参阅doc
有一件事需要注意,你有没有

not-null="true"

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

wooyq4lh

wooyq4lh2#

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

lpwwtiir

lpwwtiir3#

如果有人遇到这种情况,请确保您确实设置了正确的CascadeType(以下选项之一:All、Remove、Delete)。它需要位于您尝试删除的实体中:

public class Project {

    @Id
    private long id;

    @OneToMany(mappedBy = "project", cascade = {CascadeType.REMOVE})
    public List<Question> questions;
}

无论外键上是否有NOT NULL约束,删除操作都应该起作用,而不只是使用:

session.delete(project);
izj3ouym

izj3ouym4#

删除操作首先在项目上进行,并级联到问题,但项目删除包括问题中的project_id为空(用于引用完整性。删除问题对象时不会出现异常,但这是因为级联正在尝试将问题中的FK设为空。
看看“Java Persistence with Hibernate”,我认为你真正想要的是一个级联类型的删除或移除,而不是删除-孤儿。

相关问题