Announcement Announcement Module
Collapse
No announcement yet.
HibernateTxManager, open session, & PROPAGATION_SUPPORTS Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • HibernateTxManager, open session, & PROPAGATION_SUPPORTS

    Hi all,

    I tried using the following, pretty standard, configuration to open my hibernate session and declaratively demarcate transactions:

    Code:
    <bean id="txProxyTemplate" abstract="true" singleton="true"
    class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
        <property name="transactionManager">
          <ref bean="hibernateTransactionManager"/>
        </property>
        <property name="transactionAttributes">
          <props>
            <prop key="save*">PROPAGATION_REQUIRED</prop>
            <prop key="del*">PROPAGATION_REQUIRED</prop>
            
            <!---- NOTICE THE FOLLOWING LINE ---->
            <prop key="*">PROPAGATION_SUPPORTS,readOnly</prop>
    
          </props>
        </property>
     </bean>
    
    <bean id="aService" parent="txProxyTemplate">
        <property name="target">
          <bean class="a.service.class">
            <property name="aDao">
              <ref bean="myHibernateDao"/>
            </property>
          </bean>
        </property>
    </bean>
    Attempting to use this code resulted in HibernateTransactionManager not opening a Session unless the method name in my service object matched "save*" or "del*".

    Now, I understand than the hibernate transaction manager opens a session and creates a transaction according to the transactionAttributes but it took be quite a while to make the inverse realization that since PROPAGATION_SUPPORTS implies that a transaction will not be started (unless that is there is a surrounding tx which is not my case) the hibernate session won't be opened either.

    So, what is one supposed to do:
    • 1. avoid PROPAGATION_SUPPORTS?
      2. use a HibernateInterceptor as well (using the postInterceptors attribute of the TransactionProxyFactoryBean)?

    My opinion is that the session should be opened by the TransactionProxyFactoryBean even when using PROPAGATION_SUPPORTS.

    In any case I think this point could be made somewhere in the documentation, ie, that the session won't be opened unless a transaction is started, even if the method name is matched against the transactionAttributes.

    Best regards,
    Giorgos

  • #2
    Are you using OpenSessionInViewFilter/Interceptor for binding a session on the current request?

    Comment


    • #3
      No, I am not using either. Should I?

      I though that part of the job of HibernateTransactionManager was to manage the session (the other part being to manage transactions)...

      Best regards,
      Giorgos

      Comment


      • #4
        Yes you should. Spring doesn't open a session unless you tell it. TransactionManager needs a session otherwise the notion of transaction will not make sense and that's why it opens one.
        Read the javadocs for OSIVFilter/Interceptor and take a look at the sample application.

        Comment


        • #5
          Fair enough, but then my question is:

          Why does HibernateTransactionManager open the session when it a starts transaction? According to what you say it should be failing to find a session always if one is not opened for it in advance.

          Giorgos

          Comment


          • #6
            I haven't used the HibernateTransaction alone without the filter so I can't tell you why it's behaving like this - that's why I pointed to the java and reference docs.

            Comment


            • #7
              Thanks you for your help Costin. I am not interested in using the OSIVFilter and hence I will have to look for the answer elsewhere - I just don't know where, I've read all docs but to no avail.

              As for the HibernateInterceptor I have tried using:
              Code:
              <bean id="txProxyTemplate" abstract="true" singleton="true"
                  class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
                  <property name="postInterceptors">
                    <list><ref bean="hibernateInterceptor"/></list>
                  </property>
                  <property name="transactionManager">
                    <ref bean="hibernateTransactionManager"/>
                  </property>
                  <property name="transactionAttributes">
                    <props>
                      <prop key="save*">PROPAGATION_REQUIRED</prop>
                      <prop key="place*">PROPAGATION_REQUIRED</prop>
                      <prop key="del*">PROPAGATION_REQUIRED</prop>
                      <prop key="*">PROPAGATION_SUPPORTS,readOnly</prop>
                    </props>
                  </property>
                </bean>
              ...and it does indeed work. What concerns me is if this is the right solution.

              Thanks,
              Giorgos

              Comment


              • #8
                Indeed, PROPAGATION_SUPPORTS will not lead to a Session being created at transaction begin. Instead, a Session will be created lazily on first access, automatically synchronized with the transaction - just like it would when using JtaTransactionManager.

                The only reason to specify a HibernateInterceptor is to enforce eager creation of a Session at transaction begin. However, that shouldn't be necessary, unless you're relying on allowCreate=false in your HibernateTemplates.

                Note that as of Spring 1.2 final, allowCreate=false will still work in such a scenario: that is, it will allow creating a Session when transaction synchronization is active. The only scenario where it will throw an IllegalStateException is when there isn't even transaction synchronization active.

                As a side note: Unfortunately, Spring 1.2 final still shipped with the old allowCreate behavior for Hibernate 2.1. This has been fixed for Spring 1.2.1. All other data access strategies, including Hibernate3, should show the new allowCreate behavior.

                Juergen

                Comment


                • #9
                  Juergen,

                  Thanks a lot, your explanation confirmed what I had suspected. The "problem" is indeed that I have used getSession(false) in my DAOs (which subclass HibernateDaoSupport) in order to ensure that a session is provided to them by Spring and they don't forcefully create one on their one. I have been under the impression that this is a best-practice recommended by the Spring authors, and I for one have benefited from using it in the past.

                  I think that your response above could fit in some place in the docs even though as you say it won't be an issue from 1.2.1 onwards.

                  Best regards,
                  Giorgos

                  Comment

                  Working...
                  X