0

最近我學到了很多關於EJB3.1的知識,但顯然還不夠。這是我的悲哀的故事......EJB 3.1設計的困境 - 需要從MDB實例化有狀態的Bean

我有一個servlet的戰爭到批處理文件可以上傳。該小服務程序驗證文件,將文件數據存儲在數據庫中,併發送一條消息,以排隊接收新批次。這一切工作正常。

我有部署具有偵聽新一批收到消息的MDB的EJB-JAR的耳朵。

它也有一個有狀態的EJB(使用無接口視圖),它執行實際的批處理。 EJB引用了無狀態的JPA實體服務bean,因此需要通過容器管理來獲取容器注入的EntityManagers。

我需要在MDB收到消息時創建有狀態處理器bean的實例。我一直無法找到涵蓋此場景的任何示例/教程。

我已經試過狀態bean注入MDB,但它不工作:

[#|2011-11-24T13:25:45.470-0700|SEVERE|glassfish3.1.1|javax.enterprise.system.container.ejb.mdb.com.sun.ejb.containers|_ThreadID=21;_ThreadName=Thread-2;|MDB00050: Message-driven bean [MyProcessor-ear-1.0:MyMDB]: Exception in creating message-driven ejb : [com.sun.enterprise.container.common.spi.util.InjectionException: Exception attempting to inject Remote ejb-ref name=my.package.MyMDB/myEJB,Remote 3.x interface =my.package.MyEJB,ejb-link=null,lookup=,mappedName=,jndi-name=my.package.MyEJB,refType=Session into class my.package.MyMDB: Lookup failed for 'java:comp/env/my.package.MyMDB/myEJB' in SerialContext[myEnv={java.naming.factory.initial=com.sun.enterprise.naming.impl.SerialInitContextFactory, java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl, java.naming.factory.url.pkgs=com.sun.enterprise.naming}]|#] 

顯然,這一個糟糕的設計方法反正因爲MDB是天生無狀態如此狀態EJB不應該被注入。這是有道理的。

我的問題是怎麼回事,可我的實例化狀態EJB當MDB接收消息,並確保EJB容器是管理?

+0

爲什麼EJB需要是有狀態的? –

+0

因爲我們需要跟蹤可以獨立於其他批次更改(運行,暫停,取消)的批處理狀態。 – sdoca

+0

此外,該批處理器正在處理單個批次,因此其狀態的一部分正在跟蹤「其」批次。 – sdoca

回答

0

我們重新設計了類並將它們合併,以便MDB的onMessage方法進行處理。個人批次的狀態被存儲在MDB上的靜態地圖中。

0

如果您需要維護一個獨立於批處理(如運行,暫停,取消)的批處理狀態,即該狀態適用於在某個時刻消耗的所有MDB:爲什麼不實施EJB作爲@Singleton?通過這種方式,您可以在EJB中的實例變量中獲取該狀態,並從中讀取MDB。

+0

該狀態不適用於MDB,它適用於給定的EJB。 MDB收到一條消息,說明已收到新批次,並需要創建/啓動處理EJB。處理EJB通過另一個MDB接收狀態改變消息,它是註冊的監聽者。 – sdoca

0

您可以使用javax.jms.QueueBrowser檢查在隊列中的消息的狀態,你可以使用一個選擇器和屬性信息,以找到具體的批處理過程。