8 Replies Latest reply on Feb 17, 2008 2:49 PM by pmuir

    EntityManager not injected in onMessage method

    rmcalderero

      This is our first Seam application (Seam 2.0.0 GA on Tomcat 6) and we need now to persist in DB the data received from a jms queue.

      The jms connection works ok but then we get a NullPointerException in the last line bellow, because the entity manager is not been injected

      Are we missing something? In other asynchronous calls in other methods
      in the project the entity manager is been injected correcly. Any help would be appreciated.

      Our class:

      @Name("serviceReader")
      @Scope(APPLICATION)
      @Startup
      public class ServicioResultados implements MessageListener {
      
       @In
       private EntityManager em;
      
       @In(value = "JMSConnectionFactory")
       ConnectionFactory connectionFactory;
      
       .....
      
       @Create
       public void init() {
      
       try {
       connection = connectionFactory.createConnection();
       connection.start();
      
       session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
      
       .....
      
       public void onMessage(Message message) {
      
       log.debug("Se ejecuta el Servicio de Resultados: Nuevo mensaje......");
      
       try {
       AnalisisCerrado ac = (AnalisisCerrado) ((ObjectMessage) message).getObject();
       ac = em.merge(ac);
       ....
      


        • 1. Re: EntityManager not injected in onMessage method
          monkeyden

          Have you configured it in components.xml?

          Does the "persistence-unit-jndi-name" in components.xml match "jboss.entity.manager.factory.jndi.name" in persistence.xml?

          • 2. Re: EntityManager not injected in onMessage method
            rmcalderero

            No. The configuration we used is copied from the jpa example of the booking application. Something like this:

            Components.xml

            .....
             <transaction:entity-transaction entity-manager="#{em}"/>
            
             <persistence:entity-manager-factory name="monitorDatabase" />
            
             <persistence:managed-persistence-context name="em" auto-create="true"
             entity-manager-factory="#{monitorDatabase}"/>
            ......


            And as i said, this is been working correctly so far for our application.


            • 3. Re: EntityManager not injected in onMessage method
              nickarls

              How does your persistence.xml and datasource xml look like?

              • 4. Re: EntityManager not injected in onMessage method
                rmcalderero

                We have not used any datasource.xml so far.
                Below the persistence.xml

                <?xml version="1.0" encoding="UTF-8"?>
                <persistence xmlns="http://java.sun.com/xml/ns/persistence"
                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                 xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
                 version="1.0">
                
                 <persistence-unit name="tawmonitorDatabase" transaction-type="RESOURCE_LOCAL">
                
                 <provider>org.hibernate.ejb.HibernatePersistence</provider>
                
                
                 <class>org.fundacionctic.tawmonitor.model.Analisis</class>
                 ..........
                
                
                 <properties>
                
                 <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLInnoDBDialect"/>
                 <property name="hibernate.connection.driver_class" value="org.gjt.mm.mysql.Driver"/>
                
                 <property name="hibernate.connection.url" value="${hibernate.connection.url}"/>
                 <property name="hibernate.connection.username" value="${hibernate.connection.username}"/>
                 <property name="hibernate.connection.password" value="${hibernate.connection.password}"/>
                
                
                 <property name="hibernate.hbm2ddl.auto" value="update"/>
                 <property name="hibernate.show_sql" value="true"/>
                
                
                 <property name="current_session_context_class" value="thread"/>
                
                 <property name="hibernate.jdbc.batch_size" value="50"/>
                
                 <property name="connection.pool_size" value="3"/>
                
                 </properties>
                 </persistence-unit>
                </persistence>
                


                • 5. Re: EntityManager not injected in onMessage method
                  gsegura

                  Maybe this could this be associated with the lifecycle of the MDB being dependent on seam:

                  http://www.jboss.org/?module=bb&op=viewtopic&t=100946


                  I'll appreciate if you post back if this is the case, because I'm also about to implement a configuration similiar to yours.

                  • 6. Re: EntityManager not injected in onMessage method
                    rmcalderero

                    I tried adding manually the dependency on the entity manager in the listener class, but got the same exception...

                    In component:

                    @Name("servicioResultados")
                    @Scope(APPLICATION)
                    @Startup(depends={"em"})
                    public class ServicioResultados implements MessageListener {
                    .....


                    The exception:
                    12:17:22,567 DEBUG [ServicioResultados] Se ejecuta el Servicio de Resultados: Nuevo mensaje......
                    12:17:22,567 WARN [ActiveMQMessageConsumer] Exception while processing message: java.lang.NullPointerException
                    java.lang.NullPointerException
                     at org.fundacionctic.tawmonitor.servicios.ServicioResultados.onMessage(ServicioResultados.java:113)
                     at org.apache.activemq.ActiveMQMessageConsumer.dispatch(ActiveMQMessageConsumer.java:854)
                     at org.apache.activemq.ActiveMQSessionExecutor.dispatch(ActiveMQSessionExecutor.java:99)
                     at org.apache.activemq.ActiveMQSessionExecutor.iterate(ActiveMQSessionExecutor.java:166)
                     at org.apache.activemq.thread.PooledTaskRunner.runTask(PooledTaskRunner.java:117)
                     at org.apache.activemq.thread.PooledTaskRunner.access$100(PooledTaskRunner.java:26)
                     at org.apache.activemq.thread.PooledTaskRunner$1.run(PooledTaskRunner.java:44)
                     at edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:650)
                     at edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:675)
                     at java.lang.Thread.run(Unknown Source)
                    
                    


                    The strange thing about this is that in an asynchronous method (configured with quartz) of other component (also application scoped), we read from db with the em and we send a message to the queue. And its working ok. However the listener method of our serviceReader component is not receiving the entity manager when executed. So i also think it has something to do with the way Seam manages MessageListener components (at least in a non EJB enviroment).

                    We also tried to move the inicialization of our servicioResultados component to a method observing the seam postInitialization event:

                    @Observer("org.jboss.seam.postInitialization")
                     public void postInitialization() {
                    
                     servicioResultados.config();
                     .......
                    

                    But again the same problem.

                    I think this is a quite typical scenario, so i hope someone can give some insight on this issue.


                    • 7. Re: EntityManager not injected in onMessage method
                      rmcalderero

                      As a workaround, we have brought our code reading from the queue out of the onMessage method, an put it inside another asynchronous method periodically executed (quartz).

                      And now the entity manager is correctly being injected and we can merge our object.

                      @Asynchronous
                       public void receiveMessage(@Expiration Date begin,
                       @IntervalDuration Long interval) {
                      
                       log.debug("Se ejecuta el Servicio de Resultados......");
                      
                       try {
                      
                       Message message = consumer.receiveNoWait();
                      
                       if (message!=null) {
                      
                       AnalisisCerrado ac = (AnalisisCerrado) ((ObjectMessage) message).getObject();
                       ac = em.merge(ac);
                       .....
                      
                       }
                       }
                      
                       }

                      So it seems there are some kind of issue in the way seam manages injection in onMessage methods (or at least we havent found any solution; as i explained we have a tipical JPA-tomcat configuration). I think seam people should take a look on this.

                      If any other people can give some feedback on the topic it will be highly appreciated.




                      • 8. Re: EntityManager not injected in onMessage method
                        pmuir

                        You need to apply the Seam interceptors to your invocation properly - this would normally be done by making your Seam component an MDB. Otherwise, you need to make JMS call a proxy or something and set up Seam contexts and interception.