11 Replies Latest reply on Apr 2, 2014 1:33 PM by smarlow

    @Transactional, hibernate createQuery is not valid without active transaction

    chrisbitmead

      I've got a JSF hibernate application where the hand coded transaction stuff was becoming a bit of a mess, so I thought I'd check out the new @Transactional feature. So on my bean I've got:

       

        @Transactional

        public List<MyRec> getAllMyRec() {

        Session hsession = HibernateUtil.currentSession();

        Query query = hsession.createQuery("from MyRec");

        @SuppressWarnings("unchecked")

        List<MyRec> rtn = query.list();

        return rtn;

        }

       

      But I get:

      19:10:23,215 SEVERE [javax.enterprise.resource.webcontainer.jsf.application] (http-/0.0.0.0:8080-1) Error Rendering View[/admin/EditFlat.xhtml]: javax.el.ELException: /admin/EditFlat.xhtml @13,67 value="#{EditFlat.allMyRec}": org.hibernate.HibernateException: createQuery is not valid without active transaction

        at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:114) [jsf-impl-2.1.19-redhat-2.jar:2.1.19-redhat-2]

        at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:194) [jboss-jsf-api_2.1_spec-2.1.19.1.Final-redhat-1.jar:2.1.19.1.Final-redhat-1]

        at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:182) [jboss-jsf-api_2.1_spec-2.1.19.1.Final-redhat-1.jar:2.1.19.1.Final-redhat-1]

       

      Should I expect this to work, or do I need to do something else to make this work with hibernate, or what?

        • 1. Re: @Transactional, hibernate createQuery is not valid without active transaction
          sfcoy

          @org.springframework.transaction.annotation.Transactional is a Spring Framework annotation. I expect that you at the very least need to set up it's JSF support as well.

          • 2. Re: @Transactional, hibernate createQuery is not valid without active transaction
            chrisbitmead

            Errm, I'm talking about javax.transaction.Transactional. Seems to be a JEE7 thing, not Spring.

             

            http://stackoverflow.com/questions/17838221/jee7-do-ejb-and-cdi-beans-support-container-managed-transactions

            • 3. Re: @Transactional, hibernate createQuery is not valid without active transaction
              sfcoy

              If, on the other hand, you want to do this using JavaEE semantics without using the Spring Framework, then you should move your "getAllMyRec()" method into a @javax.ejb.Stateless EJB and delegate to it from your JSF managed bean. EJB calls are transactional by default.

               

              Something like:

              @Stateless
              public class RecordsService {
              
                @Resource
                private EntityManager em;
              
                public List<MyRec> getAllMyRec() {
                TypedQuery<MyRec> query = em.createQuery("select r from MyRec", MyRec.class);
                return query.getResultList();
                }
              
              }
              
              
              
              
              @ManagedBean
              @RequestScoped
              public class RecordsBean {
              
                  @EJB
                  private RecordsService recordsService;
              
                public List<MyRec> getAllMyRec() {
                     return recordsService.getAllMyRec();
                }   
              
              }
              
              
              • 4. Re: Re: @Transactional, hibernate createQuery is not valid without active transaction
                sfcoy

                Right. Seems I need to catch up a bit.

                 

                Make sure that you're using @javax.annotation.ManagedBean instead of @javax.faces.bean.ManagedBean

                • 5. Re: @Transactional, hibernate createQuery is not valid without active transaction
                  chrisbitmead

                  Yes I had the problem I was using javax.faces stuff, so I removed all that, converted it to javax.annotation.ManagedBean, along with other changes to make it work as purely CDI beans.

                   

                  However, I still get the same error.

                   

                  Thanks for the suggestion about using an EJB, but I'd rather avoid the complication of doubling up on beans and methods, and as I understand it, they way I have it ought to work.

                   

                  Any more thoughts?

                  • 6. Re: @Transactional, hibernate createQuery is not valid without active transaction
                    chrisbitmead

                    Interestingly, if I now put explicit transactions into my code with @Transaction, I get this error:

                     


                    Caused by: org.hibernate.TransactionException: unable to rollback against JDBC connection
                    at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.doRollback(JdbcTransaction.java:167)
                    at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.rollback(AbstractTransactionImpl.java:211)
                    ... 82 more
                    Caused by: java.sql.SQLException: You cannot rollback during a managed transaction!
                    at org.jboss.jca.adapters.jdbc.BaseWrapperManagedConnection.jdbcRollback(BaseWrapperManagedConnection.java:1110)
                    at org.jboss.jca.adapters.jdbc.WrappedConnection.rollback(WrappedConnection.java:779)
                    at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.doRollback(JdbcTransaction.java:163)
                    ... 83 more

                     

                    @Transactional

                      public List<Flatmate> getAllFlatmates() {

                      Session hsession = HibernateUtil.currentSession();

                      Transaction ex = hsession.beginTransaction();

                      try {

                      Query query = hsession.createQuery("from Flatmate");

                      @SuppressWarnings("unchecked")

                      List<Flatmate> flatmates = query.list();

                      log.error("FLATMATES: " + flatmates);

                      return flatmates;

                     

                      } finally {

                      ex.rollback();

                      }

                      }

                    • 7. Re: @Transactional, hibernate createQuery is not valid without active transaction
                      sfcoy

                      What does your Hibernate configuration look like? Is it pointing at a DataSource or have you configured a JDBC driver directly?

                      • 8. Re: Re: @Transactional, hibernate createQuery is not valid without active transaction
                        chrisbitmead

                        <?xml version="1.0" encoding="UTF-8"?>

                        <!DOCTYPE hibernate-configuration PUBLIC

                                "-//Hibernate/Hibernate Configuration DTD 3.0//EN"

                                "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

                        <hibernate-configuration>

                            <session-factory name="SessionFactory">

                                <property name="hibernate.connection.datasource">java:/jdbc/HouseDS</property>

                                <property name="hibernate.connection.driver_class">org.apache.derby.jdbc.ClientDriver</property>

                                <property name="show_sql">true</property>

                                <property name="hibernate.dialect">org.hibernate.dialect.DerbyDialect</property>

                                <property name="current_session_context_class">thread</property>

                          <mapping resource="house/datamodel/Event.hbm.xml"/>

                          <mapping resource="house/datamodel/Flatmate.hbm.xml"/>

                            </session-factory>

                        </hibernate-configuration>

                        • 9. Re: @Transactional, hibernate createQuery is not valid without active transaction
                          chrisbitmead

                          I decided to delete all the @Transactional, and do everything myself. Strangely, I now have a method that merely returns a variable:

                           

                          public List<Flatmate> getAllFlatmates() {

                            return allFlatmates;

                            }

                           

                          And get now, with no @Transactional anywhere, it seems to be creating a transaction. (I have a transaction already in progress started elsewhere.)

                           

                          Strange. Why does it decide to make a transaction for me?

                          Caused by: org.hibernate.TransactionException: nested transactions not supported

                            at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.begin(AbstractTransactionImpl.java:154) [hibernate-core-4.3.4.Final.jar:4.3.4.Final]

                            at org.hibernate.internal.SessionImpl.beginTransaction(SessionImpl.java:1435) [hibernate-core-4.3.4.Final.jar:4.3.4.Final]

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

                            at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) [rt.jar:1.8.0]

                            at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) [rt.jar:1.8.0]

                            at java.lang.reflect.Method.invoke(Method.java:483) [rt.jar:1.8.0]

                            at org.hibernate.context.internal.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:356) [hibernate-core-4.3.4.Final.jar:4.3.4.Final]

                            at com.sun.proxy.$Proxy44.beginTransaction(Unknown Source)

                            at house.screenlogic.EditFlat.<init>(EditFlat.java:27) [classes:]

                            at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) [rt.jar:1.8.0]

                            at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) [rt.jar:1.8.0]

                            at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) [rt.jar:1.8.0]

                            at java.lang.reflect.Constructor.newInstance(Constructor.java:408) [rt.jar:1.8.0]

                            at org.jboss.weld.injection.ConstructorInjectionPoint.newInstance(ConstructorInjectionPoint.java:110) [weld-core-impl-2.1.2.Final.jar:2014-01-09 09:23]

                            at org.jboss.weld.injection.ConstructorInjectionPoint.invokeAroundConstructCallbacks(ConstructorInjectionPoint.java:84) [weld-core-impl-2.1.2.Final.jar:2014-01-09 09:23]

                            at org.jboss.weld.injection.ConstructorInjectionPoint.newInstance(ConstructorInjectionPoint.java:71) [weld-core-impl-2.1.2.Final.jar:2014-01-09 09:23]

                            at org.jboss.weld.injection.producer.AbstractInstantiator.newInstance(AbstractInstantiator.java:28) [weld-core-impl-2.1.2.Final.jar:2014-01-09 09:23]

                            at org.jboss.weld.injection.producer.BasicInjectionTarget.produce(BasicInjectionTarget.java:85) [weld-core-impl-2.1.2.Final.jar:2014-01-09 09:23]

                            at org.jboss.weld.injection.producer.BeanInjectionTarget.produce(BeanInjectionTarget.java:183) [weld-core-impl-2.1.2.Final.jar:2014-01-09 09:23]

                            at org.jboss.weld.bean.ManagedBean.create(ManagedBean.java:149) [weld-core-impl-2.1.2.Final.jar:2014-01-09 09:23]

                            at org.jboss.weld.context.AbstractContext.get(AbstractContext.java:96) [weld-core-impl-2.1.2.Final.jar:2014-01-09 09:23]

                            at org.jboss.weld.bean.proxy.ContextBeanInstance.getInstance(ContextBeanInstance.java:98) [weld-core-impl-2.1.2.Final.jar:2014-01-09 09:23]

                            at org.jboss.weld.bean.proxy.ProxyMethodHandler.invoke(ProxyMethodHandler.java:78) [weld-core-impl-2.1.2.Final.jar:2014-01-09 09:23]

                            at house.screenlogic.EditFlat$Proxy$_$$_WeldClientProxy.getAllFlatmates(Unknown Source) [classes:]

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

                            at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) [rt.jar:1.8.0]

                            at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) [rt.jar:1.8.0]

                            at java.lang.reflect.Method.invoke(Method.java:483) [rt.jar:1.8.0]

                            at javax.el.BeanELResolver.getValue(BeanELResolver.java:363) [javax.el-3.0.0.jar:3.0.0]

                            ... 55 more

                          • 10. Re: @Transactional, hibernate createQuery is not valid without active transaction
                            sfcoy

                            Perhaps you should show the source for the entire class.

                             

                            I'll add that something in the EditFlat constructor is starting the transaction in question.

                            • 11. Re: @Transactional, hibernate createQuery is not valid without active transaction
                              smarlow

                              Have you enabled TRACE logging for the transaction manager?  That might help you better understand when transactions are started/ended with your application.  Some notes for enabling TRACE logging are here (category is com.arjuna).