2010-11-04 43 views
1

我正在使用EJBs ...我做了以下工作,我不知道爲什麼注入的EntityManager沒有像預期的那樣工作。EJB + POJO Helpers + EntitiyManager問題

  1. EJB1在EJB2上調用寫入數據庫的方法。
  2. 當EJB2返回時EJB1向MDB發送消息。
  3. MDB調用讀取數據庫並執行一些工作的EJB3。

我的問題是,使用@PersistenceContext注入到所有3個EJB中的EntityManager無法正常工作。在EJB2中調用persist()不會反映在EJB3中注入的EntityManager上。 什麼可能是錯誤的? 希望我讓我的問題清楚。 現在使用容器管理的交易。

+0

這是使用JPA的權利?我不太熟悉JPA,但我懷疑每個EJB都獲得了不同的EntityManager實例。當你調用persist時,你確定它沒有緩存實體並且它在數據庫中被提交?即使實體在數據庫中提交,它可能不會顯示在不同的EntityManager實例中,除非您清除其緩存並重新加載所有實體。 – jthg 2010-11-04 18:12:19

+0

是的,使用JPA。不應該有新的EntityManager實例。使用@PersistenceContext的注入重用相同的EntityManager實例,其生命週期由容器管理。那麼,我相信這會發生什麼,我不是100%肯定的。 – nico 2010-11-04 18:19:33

+0

每個EJB是否都有自己的persistence.xml文件?如果是這樣,那不是說每個EJB都擁有自己的EntityManager實例嗎? – jthg 2010-11-04 19:02:48

回答

1

我的問題是,使用@PersistenceContext注入到所有3個EJB中的EntityManager無法正常工作。在EJB2中調用persist()不會反映在EJB3中注入的EntityManager上。

在Java EE環境中,常見的情況是使用Transaction-Scoped容器管理的實體管理器。對於這樣的實體管理器,持久化上下文會在JTA事務傳播時傳播。

就你而言,我懷疑你正在爲EJB3的方法使用REQUIRES_NEW事務屬性。所以:

調用 EJB3#bar()
  • ,容器將暫停交易開始爲EJB2#foo()EJB3#bar()調用實體管理器時啓動一個新事務
  • ,一個持久化上下文將被創建。
  • 由於EJB2#foo()的事務開始尚未提交,所以更改對新持久性上下文不可見。

PS:你真的是在創建新主題嗎?如果是的話,小提醒:這是EJB規範禁止的。

+0

謝謝你的答案。將去研究它。關於線程......只是將該busisness邏輯轉換成MDB,以避免新線程......但問題仍然存在。 – nico 2010-11-08 17:03:04

+0

@nico正如所暗示的,關於各種EJB方法的事務屬性的一些細節可能會有所幫助。 – 2010-11-08 17:49:58

+0

我認爲SUPPORTS類型可能適合我的情況。但是,我認爲在改變屬性時沒有任何影響。可能這是因爲我在hibernate config xml中設置了一個JDBCTransactionFactory?我應該將其更改爲CMTTransactionFactory嗎? – nico 2010-11-08 18:11:35