Announcement Announcement Module
Collapse
No announcement yet.
Why is TransactionSynchronizationManager not being activited? Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Why is TransactionSynchronizationManager not being activited?

    I'm getting "No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here" because TransactionSynchronizationManager.isSynchronizatio nActive() is returning false. I'm using @Transactional so that Spring will manager transactions. Here's my applicationContext.xml

    Code:
    <!-- Hibernate SessionFactory -->
    	<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"
    			p:dataSource-ref="dataSource" p:mappingResources="passion.hbm.xml">
    		<property name="hibernateProperties">
    			<props>
    				<prop key="hibernate.dialect">${hibernate.dialect}</prop>
    				<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
    			</props>
    		</property>
    	</bean>
    
    	<context:annotation-config/>
    
    	<tx:annotation-driven transaction-manager="transactionManager" />
    
    	<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"
    			p:sessionFactory-ref="sessionFactory"/>
    
    	-->
    Here's the code that generates
    "No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here".

    Code:
    @SuppressWarnings("unchecked")
        @Transactional(readOnly=true)
        public List<ResponseData> getResponses(String userId, String questionnaireName, int questionNumber)
        {
            List<ResponseData> responses = (List<ResponseData>)getSessionFactory().getCurrentSession().createQuery("from ResponseData where user.userId = ? and question.questionnaire.name = ? and question.questionNumber = ?" +
            		" order by id")
            .setString(0, userId).setString(1, questionnaireName).setInteger(2, questionNumber).list();
            return responses;
        }
    When traversing SessionFactoryUtils.doGetSession, I noticed that TransactionSynchronizationManager.isSynchronizatio nActive() is false. I believe this means that Spring isn't managing the transactions. What is wrong with my configuration?

  • #2
    Do you use component scanning?

    Also make sure that the tx:annotation-driven is in the SAME applicationcontext as the classes that are @Transactional marked. If the tx:annotation-driven is in the root (ContextLoaderListener) en the other classes are in the child (DispatcherServlet) there are no transactions.

    Comment


    • #3
      Yes, I use component scanning.

      Comment


      • #4
        Configure it correctly then...

        My guess you have 2 instances of the dao, 1 in the root and one in the servlet. Let the dispatcher servlet ONLY scan for @Controllers and the one in the root scan everything BUT @Controllers.

        Comment


        • #5
          Originally posted by Marten Deinum View Post
          Configure it correctly then...

          My guess you have 2 instances of the dao, 1 in the root and one in the servlet. Let the dispatcher servlet ONLY scan for @Controllers and the one in the root scan everything BUT @Controllers.
          I did this and it still doesn't work. Would it better to not use component scanning?

          Comment


          • #6
            I found out how to fix my problem, but I do not know why the problem occurs.
            Before I tell you the fix, I will tell you what I did that I thought would work.
            My DAO has the @Repository annotation. In my root context I scan for everything except Controllers using the following
            Code:
            <context:component-scan base-package="com.kingdomglory">
             <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
            </context:component-scan>
            and only Controllers in the DispatchServlet using

            Code:
            <context:component-scan base-package="com.kingdomglory">
            <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
            </context:component-scan>
            My DAO is annotated with @Repository, so gets picked up by the root context. It also has the @Transactional annotation. Each of the DAO's methods also has the @Transactional annotation. Using this configuration, the transaction interceptors don't get invoked. However, if I remove the @Repository and @Transactional annotation and explicitly define the bean in the root context (i.e. add a bean tag in applicationContext.xml for the DAO) the transaction interceptors are invoked.

            Does anyone know why the former configuration doesn't work, but the latter configuration does?

            Comment


            • #7
              The configuration of your DispatcherServlet excludes nothing, it still scans for everything. You should specify tell the component-scan elements not to use the default-filters. Now it first registers the defaults (scan for @Component) and you are adding a @Controller. So it still scans for all the @Components.

              Start by disabling that and then add the @Controller.

              Code:
              <context:component-scan base-package="com.kingdomglory" use-default-filters="false">
                <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
              </context:component-scan

              Comment


              • #8
                Originally posted by Marten Deinum View Post
                The configuration of your DispatcherServlet excludes nothing, it still scans for everything. You should specify tell the component-scan elements not to use the default-filters. Now it first registers the defaults (scan for @Component) and you are adding a @Controller. So it still scans for all the @Components.

                Start by disabling that and then add the @Controller.

                Code:
                <context:component-scan base-package="com.kingdomglory" use-default-filters="false">
                  <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
                </context:component-scan
                I did this and added @Repository to my DAO, but I'm getting errors saying indicating that no bean was created from my DAO. I think I'll just stick to my work around. Although I'm using this code in production, currently it is a small app. As it gets bigger, I'm not going to do component scanning any way. I'm going to explicitly specify the beans in config files.

                Comment

                Working...
                X