4 Replies Latest reply on Jan 27, 2011 7:26 AM by bdorninger

    Cannot get a user TX in a thread spawned by a service POJO

    bdorninger

      Using JBoss 5.1.0GA with EJB 1.0.19 update

       

      I have a EJB service POJO (TransactionMgmType.BEAN), which spawns a thread to continuously save some statistics to the DB.

      The thread is created and started in the @PostConstruct method of the service POJO.

       

      As this spawned thread tries to do his work, I am getting:

      "java.lang.IllegalStateException: getUserTransaction() not allowed during injection (EJB3 4.4.1 & 4.5.2)"

       

      Can't I use the EJBContext in another thread?

      Why keeps the TXUtil claiming the invocation being in injection. Should be finished by the time.

       

      Any answers greatly appreciated.

       

      regards

      Bernhard

        • 1. Cannot get a user TX in a thread spawned by a service POJO
          wdfink

          Thread lifecycle handling is against the EJB specification.

          Also not a good idea because of transaction handling, the transaction might have glue to the thread.

           

          So use FutureObjects (EJB3.1) or JMS for this.

          But I suppose using JMS for this will only double the effort for DB, storing the message (if include the statistics) and than write it to the statistic tables.

          It might have sense if it is a short message and a longer calculation of statistic.

          • 2. Cannot get a user TX in a thread spawned by a service POJO
            bdorninger

            Thanks for your answer, Wolf-Dieter

             

            Right, EJB 3.0 spec chapter 21.1.2 forbids thread management from an EJB. However, since service Pojos are not part of the 3.0 spec, i had the hope to be able to solve the issue this way.

            EJB 3.1 is not an option, because the use of JBoss5.1.GA is mandatory for us.

            JMS is already involved, since data records are subscribed via a topic and collected in memory. It is required that these records shall be examined continuously, some statistical calculations shall be performed and the resulting data (along with the raw data) be flushed to the database.

             

            So we implemented it like this: an MDB subscribes to the topic and places the collected records in a concurrent map. The map and the interface for storing a record is provided by a service POJO (which is injected into the MDB instances).

            The map in the pojo is periodically checked by the mentioned thread. The transaction is not the problem, since it does not span multiple threads.

             

            I am thinking of solving this issue with an EJBTimer. Your opinion?

             

            (Anyway, the error message "...in injection...." is somewhat confusing.....)

             

            Thanks for your help again

            Bernhard

            • 3. Cannot get a user TX in a thread spawned by a service POJO
              wdfink

              I suppose that getUserTx() is inside the PostConstruct (or even in your other class implementation).

              This might force the warning, maybe you can delay it to a later point.

               

              I think if it will work for you you might do it but keep in mind that the behaviour is a bit dangerous and might produce fuzzy errors or the behaviour change with a JBoss patch or upgrade.

              • 4. Cannot get a user TX in a thread spawned by a service POJO
                bdorninger

                Dear Wolf-Dieter

                 

                GetUserTX is in the run method of the "illegal" thread. The thread is constructed and started in postConstruct of the stats pojo. The error has nothing to do with timing, since i can let it run forever and would never get a transaction. I also tried to start the thread much later - when the first data record is received from the JMS topic.  OK, since my approach is somewhat illegal in terms of the EJB spec I wouldn't call this a bug in Jboss - but again the error message seems not really appropriate.

                However, I got it working:

                The statistic service POJO gets an EntityManagerFactory injected, in postConstruct() of this POJO i acquire an entity manager.

                Then the thread is spawned and acquires an EntityTransaction from the EM (and not a userTX from the ejbCTX). I do the calculations, then save the resulting data entities with em.persist.

                After successful commit I empty the session with em.clear().

                I will keep on trying to get it working with a jbossTimerService, but this would require some more efforts: a timer service with an appropriate interval

                and a timer listener, which in turn calls the business method of our POJO

                 

                regards,

                Bernhard