当前位置: 首页 > 知识库问答 >
问题:

Hibernate EntityManager:删除不工作的引用实体

古起运
2023-03-14

我目前正在努力删除一个实体,它涉及到各种关系(只有< code > @ ManyToOne )——然而,Hibernate不删除任何东西——在调用< code>em.remove之后,一切都保持不变。

我有5个实体(< code>E1 - E5),引用问题中的实体(< code>E6)如下:

@Entity
public class EX {
    @OneToMany(mappedBy = "eX", fetch = FetchType.EAGER, cascade = { CascadeType.PERSIST, CascadeType.REMOVE })
    private Set<E6> e6s;  
}

E6本身有相反的@ManyToOne关系:

public class E6{

    @ManyToOne(optional = false)
    private E1 e1;       

    @ManyToOne(optional = false)
    private E2 e2;

    @ManyToOne(optional = false)
    private E3 e3;

    @ManyToOne(optional = false)
    private E4 e4;

    @ManyToOne(optional = false)
    private E5 e5;
}

(省略了id、附加列等...)

每当我调用< code > em . remove(instance ofe 6)时,什么都不会发生。我添加了Hibernate SQL-Output,看不到任何执行< code>DELETE查询的尝试。

由于删除可能发生在 ajax 请求和新的 EntityManager 中,因此我在删除之前添加了一个合并调用,导致我收到实体非托管异常:

em.remove(em.merge(instanceOfE6));

但是什么都没有。状态保持不变。

所以我尝试添加一个< code>@PreRemove方法,在删除实体之前清除所有关系...方法永远不会被调用。

我尝试了各种级联操作(包括Cascade.ALL)-但由于我需要的只是删除和持久化,这也应该有效。

我想过使用本机删除语句(每个实体都有一个代理项 ID,因此这很可能有效) - 但由于一切都发生在 AJAX 调用中,我不想使用它,因为我想在不重新获取每个涉及的实体的情况下更新持久性缓存......

有什么想法吗?

如果你需要更多的资料,请给我留言。

我还尝试从所有关系中删除有问题的实体(对象明智),并对剩余的实体之一调用em.merge(),希望Hibernate会鞭打未链接的实体——运气不好。

共有1个答案

邓驰
2023-03-14

我想出了问题所在 - 实际上有两个:(如果有人偶然发现类似的问题,请将其留在这里)

正如我所提到的,删除应该发生在 ajax 请求中。因此,简单的调用

em.remove(instanceOfE6);

导致了java.lang.IllegalArgumentException:正在删除分离的实例异常。因此,我尝试了使用merge的方法:

em.remove(em.merge(instanceOfE6));

这并没有产生错误——但简单的不起作用。我为Hibernate启用了跟踪日志记录,正如这篇文章中提到的:JPA/Hibernate删除实体有时无法找出问题所在,事实上,尝试删除实体会导致:

 TRACE [org...DefaultPersistEventListener] un-scheduling entity deletion ...

显然,要删除的实体仍然连接到其他实体,这导致了hibernate中止删除的问题,因此我尝试在删除之前删除关系。从E6的示例中可以看到,我使用了@ManyToOne(可选=false),这意味着我不能将传出引用设置为null,否则在调用merge时会导致异常。

我第一次尝试清理关系只是“清理集合”,因为我假设不需要清理要删除的实体的传出关系。事实并非如此,但稍后我将详细介绍这一点:

所以,代码现在看起来像

instanceOfE6.getE1().getE6s().remove(instanceOfE6);
instanceOfE6.getE2().getE6s().remove(instanceOfE6);
instanceOfE6.getE3().getE6s().remove(instanceOfE6);
instanceOfE6.getE4().getE6s().remove(instanceOfE6);
instanceOfE6.getE5().getE6s().remove(instanceOfE6);

em.remove(em.merge(instanceOfE6));

同样的问题:删除中止。我忽略了一个明显的事实,调用合并将ofc。恢复我刚刚删除的集合中的条目,因为instanceOfE6仍然在其他实体上具有不可为空的引用。因此删除再次中止。

最后给出了c。在删除引用和最终删除之前进行合并:

if (!em.contains(instanceOfE6)){
   instanceOfE6 = em.merge(instanceOfE6);
}

instanceOfE6.getE1().getE6s().remove(instanceOfE6);
instanceOfE6.getE2().getE6s().remove(instanceOfE6);
instanceOfE6.getE3().getE6s().remove(instanceOfE6);
instanceOfE6.getE4().getE6s().remove(instanceOfE6);
instanceOfE6.getE5().getE6s().remove(instanceOfE6);

em.remove(instanceOfE6);

我不太确定我是否100%准确地解释了所有内容,但至少我可以通过前后更改代码来重现和修复问题。

 类似资料:
  • 我正在使用 netbeans 并从数据库生成实体类。我所有插入和更新实体的合并调用都运行良好,但是当我尝试删除实体时,它不会将其从数据库中删除,也不会引发异常。有人可以帮我解决。我的代码如下: AbstractFacade.java AccountEntity.java DealerEntity.java

  • 问题内容: 我现在急切地尝试删除涉及各种关系的实体(仅)-但是,Hibernate不会删除任何内容- 在调用所有内容后保持不变。 我有5个实体(),像这样引用所涉及的实体(): 本身具有相反的关系: (不包括ID,其他列等) 每当我打电话时, 什么都不会 发生。我添加了Hibernate SQL- Output,但是看不到执行查询的单次尝试。 由于删除可能来自ajax请求和 新的 EntityMa

  • 正如标题所示,我无法使用delete()选项。我在网上发了很多帖子,但都找不到正确的答案。我正在Homestead上使用Laravel5.5(一周前安装,最新版本左右)。 让我给你一些代码,我真的希望有人能帮助我。 这让我头痛,奥氮平快用完了。请告诉我我做错了什么,如果遗漏了什么,请告诉我! 这是我的控制器: 这是我的索引页(索引与后端的管理索引相同: 然后是路线: 然后政策: 最后是中间件: 在

  • 我有一个Laravel项目,我试图用Storage::delete删除图像,但它似乎不起作用。我的图像位于storage\app\public\uploads文件夹中。我可以上传和编辑图像,但删除不起作用。我使用的是Laravel 8。 产品控制器。PHP PHP 网状物PHP 配置/文件系统。PHP

  • 我正在使用DocuSign REST API来自动化文档签名。我使用sender视图允许我的客户在他们的文档上放置签名选项卡并最终发送它们。 然而,我遇到了一个问题,客户机,无论出于什么原因,需要在我们的工作流中重新开始,因此放弃了嵌入,没有保存它,也没有联系我们重新启动进程。 通常,我们会调用Update将信封标记为voided并创建一个新的信封,但由于客户端没有正确退出嵌入,因此信封仍然标记为

  • 当单击按钮时,我试图删除表中的数据行。我当前的代码在1-3次按下后删除行内容,但我希望它能清除内容,然后在一次按下中添加新内容。 这是我正在使用的代码。。。 5行数据显示在jTable中。再次按下按钮后,将删除两行数据。如果我按下按钮,第二次留下一行数据。第三次按下按钮,所有行都被删除,下一次按下按钮将插入5行数据。理想情况下,我希望这个按钮总是清除行字段,然后添加插入的数据。使每个按钮按下显示新