Announcement Announcement Module
Collapse
No announcement yet.
Transaction manager and session factories, what are the transaction boundaries? Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Transaction manager and session factories, what are the transaction boundaries?

    Recently my coworker and I have realized that after familiarilizing ourselves with Spring independently we've come up with two completely different approaches to getting calls to our Hibernate DAOs into transactions. I'm sorry if my terminology isn't spot on here, though I've had a lot of success with Spring et al. some of the concepts are still kinda new to me :-)

    Just to be clear, our goal here is Hibernate sessions (database transactions?) across an entire web requests.

    The general structure of the xml is the same, and fairly typical from what I can tell. The difference is in the proxy that applies the transactions via a TransactionProxyFactoryBean.

    One approach applies the transactions to the Hibernate DAO that our typed DAOs use to retrieve their objects, like so:

    Code:
    	<bean id="hibernateDao" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
    		<property name="transactionManager">
    			<ref local="transactionManager" />
    		</property>
    		<property name="target">
    			<ref local="hibernateDaoImpl" />
    		</property>
    		<property name="transactionAttributes">
    			<props>
    				<prop key="get*">PROPAGATION_REQUIRED</prop>
    				<prop key="save">PROPAGATION_REQUIRED</prop>
    				<prop key="remove">PROPAGATION_REQUIRED</prop>
    			</props>
    		</property>
    	</bean>
    Whereas the other approach applies them to the the controller
    Code:
    	<bean id="hibernateTransactionProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
    		<property name="transactionManager">
    			<ref local="transactionManager" />
    		</property>
    		<property name="target">
    			<ref local="applicantInformationController" />
    		</property>
    		<property name="transactionAttributes">
    			<props>
    				<prop key="handleRequestInternal">PROPAGATION_REQUIRED</prop>
    			</props>
    		</property>
    	</bean>
    The first approach seems to be the example use from many tutorials but after some discussion its not entirely clear how the calls get associated with a web request-wide hibernate session. The second approach seems to run the risk of not having dao calls in validators and binders be in the session.

    An explanation of how the knowledge of the web request gets turned into a Hibernate session/transaction would be great.

    Thanks!
    Najati

  • #2
    Use OpenSessionInViewFilter or OpenSessionInViewInterceptor. See the spring JavaDocs and also this page on the Hibernate web site, which discusses the underlying concept:
    http://www.hibernate.org/43.html

    Comment


    • #3
      Yes, you sound like you're looking for OSIV.

      Note:
      - DAOs should not normally create transactions. The service layer should do that.
      - You may want to keep the session open throughout the web request (with OSIV) to simplify lazy loading (although there are some downsides to this approach, which you should understand--see the Reference Manual), but it is usually poor practice to delimit transactions in the web tier.

      Comment


      • #4
        Thanks for the responses so far. We are, indeed, using OSIV. The question I had here is a little more general. If you'll look at the bean of the type TransactionProxyFactoryBean, one's target is the DAOs, the other is the controller. We were just wondering if either of these approaches were particularly more appropriate or if either of them has any problems.

        The concern that we had with wrapping the DAOs is that its not clear how all the calls in the different DAOs for one web request get wrapped into the same transation/Hibernate session. It looks like that may be wrapping each DAO call in its own transaction, but given that this is the typical example, that seems a bit wonky.

        The concern with wrapping the controller is that, firstly, so many examples seem to do it the other way and that that might not catch things that happen outside of the handleRequestInternal.

        I hope that makes my question a little clearer :-)

        Comment


        • #5
          The concern that we had with wrapping the DAOs is that its not clear how all the calls in the different DAOs for one web request get wrapped into the same transation/Hibernate session.
          Service layer transactions span multiple DAO calls. So Spring's transaction management will automatically ensure you are working with the same session in each DAO. No special code is required in the DAOs to take advantage of this.

          It looks like that may be wrapping each DAO call in its own transaction, but given that this is the typical example, that seems a bit wonky.
          A "typical example" really has service layer transactions. Look, for example, at the PetStore. The PetClinic is perhaps a little confusing as it has no business logic and the DAO and service layer is one and the same. This is arguably not an example of good practice, and we should probably consider changing it.

          Comment


          • #6
            Thanks Rod,

            So from what I understand, the sessionFactory and transactionManager work together to create the sessions for each request (that the DAOs get to through getHibernateTemplate). That is how I thought it worked initially. The transactionProxyFactory then keeps the proxied calls in said session. Is it the case that any data access that happens within the call (or any of it's subcalls) happens in the transaction? Thus is makes sense to wrap the DAO calls to ensure that all access happens in a transaction.

            If that sounds right, I think I've got it, thanks a lot for clarifying!
            Najati

            Comment

            Working...
            X