2010-10-06 59 views
11

我知道在删除它之前我必须合并实体,但是我从来没有想过我必须在EJB内部完成它。首先我有这些:JPA:关于在删除实体之前合并实体的问题

e = (Event) scholarBean.merge(e); 
scholarBean.remove(e); 

在我的托管bean中。它给我这个错误

java.lang.IllegalArgumentException: Entity must be managed to call remove: [email protected], try merging the detached and try the remove again. 

于是我把这两行我的会话bean中,和它的作品。任何想法为什么?

Managed Bean

myEJB.java

public void deleteEvent(Event e){ 
    e = (Event) merge(e); 
    em.remove(e); 
} 

回答

17

我知道我必须取出

之前合并的实体

不完全。传递给删除的对象必须是实体,不能分离。那不一样。

但我从来没有想过我必须在EJB内部这样做。首先,我有这些(...)

让我们来看看你在做什么:

1: e = (Event) scholarBean.merge(e); 
2: scholarBean.remove(e); 

所以在1:,你调用EJB(很可能与事务范围的持久化上下文),其合并实体。但是,然后方法结束,事务提交,持久性上下文被关闭,使得返回的实体再次脱离

而在2:中,您将(仍然)已分离的实体传递给EJB并尝试使用remove它,这是不允许的。和KaBOOM!

因此,然后我将这两行放入会话bean中,并且工作正常。任何想法为什么?

它的工作原理,因为你现在关联到JTA事务的持久化上下文的范围内的工作,你真的这样传递一个管理实体remove

+0

精彩的回答。非常感谢你 – 2010-10-07 00:36:15

+0

@哈里不客气。 – 2010-10-07 08:26:33

7

...,你甚至可以将那些:

像这样:

public void deleteManCheck(ManCheck manCheck) { 
    em.remove(em.merge(manCheck)); 
} 
2

我有同样的交易问题时,这是在一个servlet使用。从MDB使用EJB-service-bean时,它工作良好,因为事务是在调用EJB之前启动的,但是当EJB调用来自servlet时,没有正在运行的事务。 我通过创建一个启动并调用UserTransaction的过滤器来解决此问题。然后,每次调用EJB方法都会加入我的UserTransaction,而不是启动它自己的事务。