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



我目前正在努力删除一个涉及各种关系的实体(只有@ManyToOne)-然而,Hibernate不会删除任何内容-在调用em.remove后,一切都保持不变。


我有5个实体(E1 - E5),引用有问题的实体(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、附加列等)


每当我调用em.remove(instanceOfE6)时,只要就不会发生任何事情。我添加了Hibernate SQL输出,并且看不到执行DELETE查询的任何一次尝试。

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

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

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

所以我尝试添加一个@PreRemove方法来清除所有关系,然后再删除实体。。。方法永远不会被调用。

我尝试了各种级联操作(包括Cascade.ALL),但由于我所需要的只是删除和持久化,所以应该也能正常工作。


我曾想过使用本机Delete语句(每个实体都有一个代理id,所以这很可能会起作用),但由于所有事情都发生在AJAX调用中,我不想使用它,因为我想在不重新获取每个相关实体的情况下更新Persistence Cache。。。

有什么想法吗?

如果你需要更多的消息来源,请给我留言。


我还试图从所有关系中删除有问题的实体(按对象),并在剩下的一个实体上调用em.merge(),希望hibernate会鞭打未链接的实体——运气不好。

我发现了问题-实际上有两个问题:(如果有人遇到类似的问题,请留在这里)

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

em.remove(instanceOfE6);

导致CCD_ 12异常。因此,我尝试了使用合并的方法:

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

这并没有产生错误,但simple不起作用。我为hibernate启用了跟踪日志记录,如本文所述:JPA/hibernate删除实体有时无法找出问题所在,事实上,试图删除实体导致:

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

显然,要删除的实体仍然连接到其他实体,这导致hibernate中止删除的问题,所以我试图在删除之前删除关系。从E6的示例中可以看到,我使用了@ManyToOne(optional = 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));

同样的问题:删除已中止。我错过了一个显而易见的事实,那就是调用merge将失败。恢复我刚刚删除的集合中的条目,因为instanceOfE6在其他实体上仍然有不可为null的引用。因此,删除操作再次中止。

最后给出了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%准确地解释了所有内容,但至少我可以通过来回更改代码来复制和修复问题。

最新更新