1 2 Previous Next 16 Replies Latest reply on Nov 8, 2013 2:27 AM by olpf

    CMT no commit

    olpf

      Hi,

       

      I am using Hibernate 4, JBoss 7.1.1 in my JPA 2 application. All is working fine in junit tests with HSQL db and manual transaction commit. But if I deploy the application in JBoss the db schema generation works but no data is inserted in the tables. There is no exception or something. I configured the data source as JTA. Also I set org.hibernate.service.jta.platform.internal.JBossAppServerJtaPlatform in persistence.xml.

       

      I instantiate the EntityManagerFactory by myself and also the EntityManager because I cannot use CDI there because I only know on request time which data source to use. Therefore the data source name is not defined in the persistence.xml. It will be added on EntityManagerFactory instantiation programmatically.

       

      To get the hibernate db schema working I used a single EJB with TransactionManagementType.BEAN no avoid being in a CMT there.

       

      I tried to test the transaction manually and got a exception that a CMT cannot be committed manually. This seems like that a CMT is existing. But I do not know why it is not committed by the server.

       

      Any ideas?

       

      Cheers

      Oliver

        • 1. Re: CMT no commit
          smarlow

          I don't understand how your creating the EntityManagerFactory (a short code example could help explain).

           

          Sounds like you don't have Hibernate configured to know about the transaction manager.  You could use @PersistenceUnit instead to get an EntityManagerFactory (if you want to control the lifecycle of the persistence context).  Or, you could use @PersistenceContext to get an EntityManager (allowing the EE container to control the persistence context).

           

          You also could try the latest nightly build of WildFly 8 which has a newer version of Hibernate (more likely to detect the transaction manager for you).

          • 2. Re: CMT no commit
            olpf

            The problem is that I cannot configure the data source name in the persistence.xml because I have to handle the connection to different databases. So the signature of the ejb method are containing an object which identifies by naming convention the data source name.

             

            So I created a class EntityManagerFactoryCache which caches the EntityManagerFactory instances for each data source.

            The EntityManager creation looks like this:

             

            @Lock(LockType.WRITE)

            @Override

            public synchronized EntityManager determineEntityManager(String applicationName)

                          throws EntityManagerFactoryException

            {

                

                 // emfCache is a Map<String, EntityManagerFactory >

                 EntityManagerFactory emf = emfCache.get(applicationName);

             

                 if (emf == null) {

                      String dsName = this.dataSourceProvider.getDataSourceName(applicationName);

                      Map<String, String> props = new HashMap<>();

                      props.put("javax.persistence.jtaDataSource", dsName);

                      props.put("hibernate.hbm2ddl.auto", "update");

             

                      emf = Persistence.createEntityManagerFactory("mypersistenceunit", props);

                      emfCache.put(applicationName, emf);

                 }

                

                 EntityManager em = emf.createEntityManager();

                 return em;

            }

             

            Is it only possible to use CMT when the container injects the EntityManager? If yes, is there a possiblity to have a dynamic data source name with CDI?

             

             

            I forgot:

             

            I thought hibernate knows the transaction manager by setting in persistence.xml:

             

            <property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.JBossAppServerJtaPlatform" />

             

            I have many logs from hibernate like this:

             

            13:53:40,300 DEBUG [org.hibernate.ejb.AbstractEntityManagerImpl] (http--0.0.0.0-9090-1) Looking for a JTA transaction to join

            13:53:40,301 DEBUG [org.hibernate.ejb.AbstractEntityManagerImpl] (http--0.0.0.0-9090-1) Unable to join JTA transaction

            13:53:40,301 DEBUG [org.hibernate.engine.transaction.internal.TransactionCoordinatorImpl] (http--0.0.0.0-9090-1) Skipping JTA sync registration due to auto join checking

             

             

            Debug shows as tx member of EntityManagerImpl: org.hibernate.ejb.TransactionImpl

            transactionType of EntityManagerImpl is PersistenceUnitTransactionType "JTA"

            • 3. Re: CMT no commit
              olpf

              Data source name dsName is for instance "java:jboss/datasources/MyDatabaseNameWithPrefix"

              • 4. Re: CMT no commit
                olpf

                With wildfly 8.0.0 alpha1 I get a

                 

                java.lang.NoClassDefFoundError: org/jboss/el/cache/FactoryFinderCache

                 

                on deployment of the ear (which is not the case iwht jboss 7.1.1)

                • 5. Re: CMT no commit
                  olpf

                  Probably because I instantiate the EntityManager by myself the container cannot do a commit because it is not aware of the EntityManager. This means I cannot use CMT? Is this correct?

                  • 6. Re: CMT no commit
                    olpf

                    By now I got the data in the DB removing JTA completely. I changed to transaction-type="RESOURCE_LOCAL" commit by my own. Also UserTransaction with JTA does not work. Also the "Unable to join JTA transaction" is logged by hibernate. Probably hibernate 3 would be an option?

                    • 7. Re: CMT no commit
                      olpf

                      I fixed the data source name in the persistence.xml and injected the EntityManager and it works. Unfortunately I need dynamic data sources. On invocation of the ejb method I now which database is meant.

                      Is there a possiblity to register my self instantiated EntityManager that JBoss likes to work with it? Probably in jndi or something?

                      • 8. Re: CMT no commit
                        jkronegg

                        I use a custom PersistenceProvider which extends HibernatePersistence and overrides the createContainerEntityManagerFactory(..) and createEntityManagerFactory(..). When called, these methods change dynamically the datasource, respectively the datasource name. You can get the details on http://stackoverflow.com/a/19831074/698168

                        • 9. Re: CMT no commit
                          smarlow

                          Julien, Interesting approach!  If you have performance changes for Hibernate, you can also contribute them (see the community section on hibernate.org).

                           

                          Did you work out your issues Oliver?  I didn't pay as much attention to this thread because the title didn't draw my attention when you had updates.  You could enable trace logging for org.jboss.as.jpa + com.arjuna as mentioned here, to get more insight as to what is going on.

                          • 10. Re: CMT no commit
                            olpf

                            Thanks for your replies. I had to check this because I working on another project...but I got it working by leaving the transaction type to RESOURCE_LOCAL and using BMT with @TransactionManagement(TransactionManagementType.BEAN) in my EJB.

                            Disadvantage is that I have to do this in each EJB method:

                             

                            EntityManager em = emfCache.determineEntityManager(..,);

                            EntityTransaction et = em.getTransaction();

                            et.begin();

                            // do some db stuff

                            et.commit();

                             

                            And rollback if something was wrong and a exception is thrown. I haven't found another way then to achieve CMT.

                            • 11. Re: CMT no commit
                              smarlow

                              With CMT and transaction type JTA, what happens if you call em.joinTransaction()?

                               

                              someBeanMethod() {

                                EntityManager em = emfCache.determineEntityManager(..,);

                                em.joinTransaction();

                                // do some db stuff

                              }

                              • 12. Re: CMT no commit
                                olpf

                                I am getting this:

                                 

                                Caused by: java.lang.NullPointerException

                                  at org.hibernate.engine.transaction.internal.jta.JtaStatusHelper.getStatus(JtaStatusHelper.java:73) [hibernate-core-4.2.4-SNAPSHOT.jar:4.2.4.SNAPSHOT]

                                  at org.hibernate.engine.transaction.internal.jta.JtaStatusHelper.isActive(JtaStatusHelper.java:115) [hibernate-core-4.2.4-SNAPSHOT.jar:4.2.4.SNAPSHOT]

                                  at org.hibernate.engine.transaction.internal.jta.CMTTransaction.join(CMTTransaction.java:149) [hibernate-core-4.2.4-SNAPSHOT.jar:4.2.4.SNAPSHOT]

                                  at org.hibernate.ejb.AbstractEntityManagerImpl.joinTransaction(AbstractEntityManagerImpl.java:1230) [hibernate-entitymanager-4.2.4-SNAPSHOT.jar:4.2.4.SNAPSHOT]

                                  at org.hibernate.ejb.AbstractEntityManagerImpl.postInit(AbstractEntityManagerImpl.java:178) [hibernate-entitymanager-4.2.4-SNAPSHOT.jar:4.2.4.SNAPSHOT]

                                  at org.hibernate.ejb.EntityManagerImpl.<init>(EntityManagerImpl.java:89) [hibernate-entitymanager-4.2.4-SNAPSHOT.jar:4.2.4.SNAPSHOT]

                                  at org.hibernate.ejb.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:193) [hibernate-entitymanager-4.2.4-SNAPSHOT.jar:4.2.4.SNAPSHOT]

                                  at org.hibernate.ejb.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:188) [hibernate-entitymanager-4.2.4-SNAPSHOT.jar:4.2.4.SNAPSHOT]

                                  at com...emf.EntityManagerFactoryCacheImpl.determineEntityManager(EntityManagerFactoryCacheImpl.java:115) [--commons-emf-service-ejb-x-SNAPSHOT.jar:x-SNAPSHOT]

                                  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [rt.jar:1.7.0_45]

                                  at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) [rt.jar:1.7.0_45]

                                  at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) [rt.jar:1.7.0_45]

                                  at java.lang.reflect.Method.invoke(Unknown Source) [rt.jar:1.7.0_45]

                                  at org.jboss.as.ee.component.ManagedReferenceMethodInterceptorFactory$ManagedReferenceMethodInterceptor.processInvocation(ManagedReferenceMethodInterceptorFactory.java:72) [jboss-as-ee-7.1.1.Final.jar:7.1.1.Final]

                                  at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.1.Final.jar:1.1.1.Final]

                                  at org.jboss.invocation.InterceptorContext$Invocation.proceed(InterceptorContext.java:374) [jboss-invocation-1.1.1.Final.jar:1.1.1.Final]

                                  at org.jboss.as.weld.ejb.Jsr299BindingsInterceptor.doMethodInterception(Jsr299BindingsInterceptor.java:127) [jboss-as-weld-7.1.1.Final.jar:7.1.1.Final]

                                  at org.jboss.as.weld.ejb.Jsr299BindingsInterceptor.processInvocation(Jsr299BindingsInterceptor.java:135) [jboss-as-weld-7.1.1.Final.jar:7.1.1.Final]

                                  at org.jboss.as.ee.component.interceptors.UserInterceptorFactory$1.processInvocation(UserInterceptorFactory.java:36) [jboss-as-ee-7.1.1.Final.jar:7.1.1.Final]

                                  at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.1.Final.jar:1.1.1.Final]

                                  at org.jboss.invocation.WeavedInterceptor.processInvocation(WeavedInterceptor.java:53) [jboss-invocation-1.1.1.Final.jar:1.1.1.Final]

                                  at org.jboss.as.ee.component.interceptors.UserInterceptorFactory$1.processInvocation(UserInterceptorFactory.java:36) [jboss-as-ee-7.1.1.Final.jar:7.1.1.Final]

                                  at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.1.Final.jar:1.1.1.Final]

                                  at org.jboss.invocation.InterceptorContext$Invocation.proceed(InterceptorContext.java:374) [jboss-invocation-1.1.1.Final.jar:1.1.1.Final]

                                  at org.jboss.as.ejb3.concurrency.ContainerManagedConcurrencyInterceptor.processInvocation(ContainerManagedConcurrencyInterceptor.java:104) [jboss-as-ejb3-7.1.1.Final.jar:7.1.1.Final]

                                  at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.1.Final.jar:1.1.1.Final]

                                  at org.jboss.as.ejb3.tx.EjbBMTInterceptor.handleInvocation(EjbBMTInterceptor.java:105) [jboss-as-ejb3-7.1.1.Final.jar:7.1.1.Final]

                                  ... 118 more

                                 

                                 

                                I set in persistence.xml to JTA and changed EJB to TransactionManagementType.CONTAINER. Do not know why BMTInterceptor is used.

                                • 13. Re: CMT no commit
                                  smarlow

                                  I expect that BMT interceptor should be used because you mentioned using @TransactionManagement(TransactionManagementType.BEAN) before.  If you switch to CONTAINER, the CMT interceptor should be used.

                                   

                                  If you still get a NullPointerException after switching to CONTAINER, I will wonder if Hibernate is finding the TransactionManager properly.

                                  • 14. Re: CMT no commit
                                    olpf

                                    As mentioned it was changed to TransactionManagementType.CONTAINER.

                                    1 2 Previous Next