Hibernate EntityManager:删除引用的实体不工作 [英] Hibernate EntityManager: remove referenced entity not working

查看:135
本文介绍了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(可选= false)
私人E1 e1;

@ManyToOne(可选= false)
私人E2 e2;

@ManyToOne(可选= false)
私人E3 e3;

@ManyToOne(可选= false)
私人E4 e4;

@ManyToOne(可选= false)
私人E5 e5;

(留下ids,附加栏等等)






每当我调用 em.remove(instanceOfE6)时,只需 nothing 发生。我添加了Hibernate SQL-Output,并且看不到执行 DELETE Query的单个尝试。



发生在ajax请求和新鲜 EntityManager中,我在删除之前添加了对合并的调用,导致otherwhise获得实体非托管异常

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

但没有。状态保持不变。



所以我试着添加一个 @PreRemove 方法来清除所有关系...方法从来没有被调用过。



我尝试了各种级联操作(包括 Cascade.ALL ) - 我需要的只是删除并坚持下去,那也应该是一样的。




我想过使用原生的Delete语句(每个实体都有一个代理ID,所以很可能会起作用) - 但因为所有事情都是在AJAX调用中发生的,所以我不想使用它,因为我希望更新持久缓存而不必重新获取每个涉及到的实体......



任何想法?



如果您需要更多资源,请给我留言。




我也尝试从所有关系中删除实体(对象明智),并调用 em.merge()在剩下的其中一个实体上,希望hibernate能够鞭the未链接的实体 - 没有运气。



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

  em.remove(instanceOfE6); 

导致 java.lang.IllegalArgumentException:删除分离的实例 code>异常。所以,我尝试了使用merge的方法:

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

没有产生错误 - 但简单的行不通。我启用了这个帖子中提到的hibernate的跟踪日志记录: JPA / Hibernate删除实体有时候无法正常工作来找出问题所在,实际上,试图删除实体导致:

  TRACE [org ... DefaultPersistEventListener]取消调度实体删除... 

显然,要删除的实体是仍然连接到其他实体,这导致了休眠中止删除的问题,所以我试图在删除之前删除关系。
正如您从 E6 的例子中看到的,我使用了 @ManyToOne(可选= false),这意味着我无法将外向引用设置为null,否则在调用 merge 时会导致异常。


我第一次尝试清理关系只是清理集合,因为我认为清理我想要删除的实体的传出关系不是必需的。它不是,但稍后我会详细介绍这一点:



所以,现在的代码看起来像

  instanceOfE6.getE1()getE6s()除去(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 willc。恢复我刚删除的集合中的条目,因为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%准确,但至少我可以通过来回更改代码来重现和修复问题。

I'm currenetly trying hard to delete an entity, that is involved in various relations (Only @ManyToOne) - However, Hibernate does not delete anything - after calling em.remove everything remains unchanged.


I have 5 entities (E1 - E5), referencing the entity (E6) in question like this:

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

E6 itself has the reverse @ManyToOne Relations:

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;
}

(left out ids, additional columns etc...)


Whenever I call em.remove(instanceOfE6), simply nothing happens. I added Hibernate SQL-Output and cannot see a single attempt of executing a DELETE Query.

Since the deletion can happen from an ajax request and a fresh EntityManager, I added a call to merge before the deletion, cause otherwhise I get an Entity unmanaged Exception:

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

But nothing. State remains unchanged.

So I tried to add an @PreRemove Method to clear all the relations before removing the entity... Method gets never called.

I tried various Cascade Operations (Including Cascade.ALL) - but since all I need is remove and persist, that should be working as well.


I thought about using a native Delete Statement (each entity has a surrogate id, so that would most likely work) - but since everything happens from within an AJAX-call, I don't want to use that, cause I want to have the Persistence-Cache updated without re-fetching every involved Entity...

Any ideas?

If you need more source, just drop me a comment.


I also tried to remove the entity in question from ALL relations (object wise), and call em.merge() on one of the remaining entities, hoping that hibernate will whipe the unlinked entity - no luck.

解决方案

I figured out the problem(s) - Actual there have been two of them: (Leaving this here, if somebody stumbles across a similar issue)

As I mentioned, the deletion should have happened in an ajax request. Therefore, simple calling

em.remove(instanceOfE6);

resulted in an java.lang.IllegalArgumentException: Removing a detached instance exception. So, I tried the approach using merge:

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

which did not produce an error - but simple didn't work. I enabled trace-logging for hibernate as mentioned in this post: JPA/Hibernate remove entity sometimes not working to figure out what went wrong, and indeed, trying to remove the entity resulted in:

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

Obviously the entity to remove is still connected to other entities, which lead to the problem that hibernate aborted the deletion, so i tried to remove the relations before deletion. As you can see from the example of E6, I used @ManyToOne(optional = false), which means I cannot set the outgoing references to null, or it will cause exceptions when calling merge.

My first attempt to clean the relations was only "cleaning the sets", because I assumed that cleaning the outgoing relations of the entity I want to delete is not required. It is not, but i'll outline this in detail a little later:

So, the code now looked like

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

Same issue: deletion aborted. I missed the obvious fact, that calling merge will ofc. restore the entries inside the sets i just removed, because instanceOfE6 STILL had it's not nullable-references on the other entities. Therefore deletion was aborted again.

Finally the solution ofc. was to do the the merge before removing the references and the final deletion:

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


I'm not quite sure if I explained everything 100% accurate, but at least I can reproduce and fix the Issue by changing the code back and forth.

这篇关于Hibernate EntityManager:删除引用的实体不工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆