4 Replies Latest reply on Sep 18, 2006 6:40 PM by holmes.j

    TransactionException: could not register synchronization roo

    holmes.j

      So we've just decided to jump on the Hibernate/EJB3 bandwagon. We were using EJB2.1 before. I'm not really familiar with much of that as I just joined, but it looks nasty.

      Anyways, I've got Hibernate working in our test environment, following the CaveatEmptor example rather closely.

      However, once deployed to JBoss, it's just not working. I'm trying to use JTA to manage the transactions, but something somewhere isn't making the connection it needs too.

      In our SessionBean, once the Dao is called, it decides it wants to throw an Exception with the message: "load is not valid without active transaction". I'm betting it's root is a NPE, but I haven't navigated that far deep.

      To make sure it wasn't the SessionBean that was causing the problem, I just threw a line in a jsp to get the Dao. That comes back with a org.hibernate.TransactionException: could not register synchronization, who's root cause is a NPE from the transaction in JTATransaction.registerSynchronization() (line 306)

      So, I don't really know how to get this stuff to work. Below is my hibernate.properties file.

      hibernate.c3p0.min_size=5
      hibernate.c3p0.max_size=20
      hibernate.c3p0.timeout=1800
      hibernate.c3p0.max_statements=50
      
      hibernate.current_session_context_class=jta
      hibernate.transaction.factory_class=org.hibernate.transaction.JTATransactionFactory
      hibernate.transaction.manager_lookup_class=org.hibernate.transaction.JBossTransactionManagerLookup
      hibernate.transaction.flush_before_completion=true
      hibernate.transaction.auto_close_session=true
      
      hibernate.cache.provider_class=org.hibernate.cache.NoCacheProvider
      hibernate.show_sql=true
      hibernate.format_sql=true
      hibernate.generate_statistics=true
      
      hibernate.bytecode.use_reflection_optimizer=false
      hibernate.bytecode.provider=javassist
      


      Any idea on what else I have to do to get transactions to work with JTA?

      Thanks,
      Jason

        • 1. Re: TransactionException: could not register synchronization
          holmes.j

          I guess I forgot some slightly useful information.

          JBoss 4.04GA
          Hibernate 3.2CR2
          Hibernate Annotations 3.2.0CR1

          • 2. Re: TransactionException: could not register synchronization
            holmes.j

            So the design I'm going for is something like the one described in this thread http://forum.hibernate.org/viewtopic.php?t=927886 or this one http://www.hibernate.org/328.html.

            It's where the Business objects have no clue where or how the objects come from, they just talk to a Dao, and are merry.

            So I guess the problem is that I wasn't starting a Transaction anywhere. I blindly assumed that automagically Hibernate would create a Transaction object during the getCurrentSession(), if it was setup to use JTA.

            Obviously that's not the case, and the answer is to use AOP to invoke a session like this http://www.hibernate.org/391.html. Never played with AOP before, but that's a different discussion.

            Does this sound right?

            -Jason

            • 3. Re: TransactionException: could not register synchronization
              holmes.j

              I'm going crazy trying to figure this out.

              So I was reading the Hibernate docs again and came across this ...


              With CMT, transaction demarcation is done in session bean deployment descriptors, not programatically, hence, the code is reduced to:

              // CMT idiom
              Session sess = factory.getCurrentSession();

              // do some work
              ...

              In a CMT/EJB even rollback happens automatically, since an unhandled RuntimeException thrown by a session bean method tells the container to set the global transaction to rollback. This means you do not need to use the Hibernate Transaction API at all with BMT or CMT, and you get automatic propagation of the "current" Session bound to the transaction.


              So I was write, it is supposed to automagically create the Transaction. I was stepping through my session bean, and it looks like it did create a transaction, it's just that it hasn't started the transaction. This then throws the HibernateException because the transaction is not in a valid state.

              Anybody know how to use EJB Session Beans w/ Hibernate, JTA and all this wonderful stuff?

              • 4. Re: TransactionException: could not register synchronization
                holmes.j

                In the hope that somebody can help ...

                I have a EJB 2.1 Stateless Session Bean with this header ...

                /**
                 * @ejb.bean name="GeoFeatureServer"
                 * jndi-name="com.free2be.framework.gis.feature.GeoFeatureServerHome"
                 * type="Stateless" view-type="remote"
                 * @ejb.transaction type="Required"
                 */

                , that does this ...
                /**
                 * @ejb.interface-method
                 */
                 public GeoFeature findGeoFeature(GeoFeaturePk geoFeaturePk) throws NoSuchElementException {
                 GeoFeature value = (GeoFeature) cache.getByKey(geoFeaturePk);
                 if (value == null) {
                 getLogger().debug(geoFeaturePk + " not cached...loading");
                 GeoFeature featureValue = getGeoFeatureDao().findById(geoFeaturePk, false);
                 value = new GeoFeature(featureValue);
                 cache.addToCache(value);
                 }
                 return value;
                 }


                and my Dao looks like this ...
                 @SuppressWarnings("unchecked")
                 public V findById(long id, boolean lock) {
                 V entity;
                 try {
                 Session session = getSession();
                // Transaction tx = session.beginTransaction();
                 if (lock)
                 entity = (V) session.load(getPersistentClass(), id, LockMode.UPGRADE);
                 else
                 entity = (V) session.load(getPersistentClass(), id);
                 } catch (HibernateException e) {
                 throw new NoSuchElementException(e.getMessage());
                 }
                
                 return entity;
                 }
                


                If I take out the session.beginTransaction, I get the "load is not valid without active transaction." If I leave it in, it works like it should.

                Any ideas as to what/how I'm supposed to configure to get the Application Server to do what it's supposed to do?

                -Jason