2010-10-06 55 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,而不是啓動它自己的事務。