Domanda

I have learned a lot about EJB3.1 lately, but apparently not enough. Here's my tale of woe...

I have a war with servlet to which batch files can be uploaded. The servlet validates the file, stores the file data in a database and sends a message to queue that a new batch has been received. This all works fine.

I have an ear with an ejb-jar deployed which has an MDB that listens for the new batch received messages.

It also has a stateful EJB (using the no-interface view) that does the actual batch processing. The EJB has references to stateless JPA entity service beans and therefore needs to be container managed to get container injected EntityManagers.

I need to create an instance of the stateful processor bean whenever a message is received by the MDB. I haven't been able to find any examples/tutorials which cover this scenario.

I have tried injecting the stateful bean into the MDB, but it doesn't work:

[#|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}]|#]

Apparently this a bad design approach anyway because MDBs are inherently stateless so stateful EJBs shouldn't be injected. This makes sense.

My question is how else can I instantiate my stateful EJB when the MDB receives a message and ensure that the EJB is container managed?

È stato utile?

Soluzione 2

We redesigned the classes and merged them so that the onMessage method of the MDB does the processing. The state of the individuals batches are being stored in a static map on the MDB.

Altri suggerimenti

If you need to maintain a single state for batch processing as you pointed out above (running, paused, cancelled) independently of the batches, i.e. the state applies to all MDBs consuming in certain moment: why don't you implement the EJB as a @Singleton? This way you could have that state in an instance variable in your EJB and your MDB reading from it.

You can use javax.jms.QueueBrowser to inspect the state of Messages in Queue, and you could use a selector and a property message to locate the concrete batch process.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top