Page 1 of 3 123 LastLast
Results 1 to 10 of 24

Thread: Nested Transactions and propogation_required

  1. #1
    Join Date
    Aug 2004
    Location
    New York
    Posts
    168

    Default Nested Transactions and propogation_required

    I have a message driven bean which calls a save method on a DAO class. I have the DAO save method declaratively wrapped in a Propogation_required transaction. The transaction manager managing this transaction is the HibernateTransactionManager. The message driven bean calling the DAO is within a jboss container managed transaction. When the MDB calls the DAO I get an exception. It seems as if there is a problem having a JDBC transaction nested within a container managed transaction. The behaviour i am looking for is that the DAO simply participates in the Message Driven Bean transaction. I'll paste some of the exception below. Thanks.

    Karl

    Caused by: java.sql.SQLException: You cannot commit during a managed transaction!
    at org.jboss.resource.adapter.jdbc.BaseWrapperManaged Connection.jdbcCommit()V(BaseWrapperManagedConnect ion.java:
    525)
    at org.jboss.resource.adapter.jdbc.WrappedConnection. commit()V(WrappedConnection.java:464)
    at net.sf.hibernate.transaction.JDBCTransaction.commi t()V(JDBCTransaction.java:63)
    at org.springframework.orm.hibernate.HibernateTransac tionManager.doCommit(Lorg.springframework.transact ion.suppo
    rt.DefaultTransactionStatusV(HibernateTransactionManager.java:386)
    at org.springframework.transaction.support.AbstractPl atformTransactionManager.commit(Lorg.springframewo rk.transa
    ction.TransactionStatusV(AbstractPlatformTransactionManager.java:376)
    at org.springframework.transaction.interceptor.Transa ctionAspectSupport.doCommitTransactionAfterReturni ng(Lorg.s
    pringframework.transaction.interceptor.Transaction AspectSupport$TransactionInfoV(TransactionAspectSupport.java:278)
    at org.springframework.transaction.interceptor.Transa ctionInterceptor.invoke(Lorg.aopalliance.intercept .MethodIn
    vocationLjava.lang.Object;(TransactionInterceptor.java:67)
    at org.springframework.aop.framework.ReflectiveMethod Invocation.proceed()Ljava.lang.Object;(ReflectiveM ethodInvo
    cation.java:140)

  2. #2
    Join Date
    Aug 2004
    Location
    Linz, Austria
    Posts
    391

    Default

    Do not combine a local transaction strategy like HibernateTransactionManager with JTA or EJB CMT. Rather, use Spring's JtaTransactionManager here, which will automatically participate in existing J2EE container transactions, providing transaction-scoped Hibernate Sessions for them just like HibernateTransactionManager.

    Alternatively, do not use Spring transaction management at all, but just rely on EJB CMT. As long as you specify an appropriate TransactionManagerLookup in Hibernate's configuration, Spring's HibernateTemplate will auto-detect the J2EE container transaction and provide transaction-scoped Hibernate Sessions for it, just like it does for Spring-managed transactions.

    Juergen

  3. #3
    Join Date
    Aug 2004
    Location
    New York
    Posts
    168

    Default

    I have tried to configure my hibernate session factory to use Jboss J2EE transactions but have been unsuccessful thus far. My problem is that I am using Lazy loading via the OpenSessionInView filter, but when I change to J2EE transactions, SessionFactoryUtils does not seem to be able to find my open session. My spring xml context configuration is pasted below:

    Code:
    <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
        <property name="jndiName"><value>java&#58;/ClassesDataSource</value></property>
    </bean>
    
    <bean id="jtaTransactionManager"   class="org.springframework.jndi.JndiObjectFactoryBean">
        <property name="jndiName"><value>java&#58;/TransactionManager</value></property>
    </bean>
    
    <!-- Hibernate SessionFactory -->
    <bean id="sessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
    	<property name="dataSource"><ref bean="dataSource"/></property>
    	
    
    	<property name="mappingResources">
    		<ref bean="configBeanMappings"/>
    	</property>
    		
    
    	<property name="hibernateProperties">
    		<props>
    		  <prop key="hibernate.dialect">net.sf.hibernate.dialect.SQLServerDialect</prop>
    		  <prop key="hibernate.cache.use_query_cache">true</prop>
    		  <prop key="hibernate.show_sql">true</prop>
    		  <prop key="hibernate.transaction.manager_lookup_class">
           net.sf.hibernate.transaction.JBossTransactionManagerLookup
         </prop>
    		</props>
    	</property>
    		
    	<property name="jtaTransactionManager">
    		<ref bean="jtaTransactionManager"/>
    	</property>
    </bean>

    I think I have traced the issue down to the method below, but I am not quite sure what the proper behavior is when using a J2EE Transaction Manager.

    Code:
    private static Session getSession&#40;SessionFactory sessionFactory, Interceptor entityInterceptor,
                                      SQLExceptionTranslator jdbcExceptionTranslator,
                                      boolean allowSynchronization, boolean allowCreate&#41;
    Thanks for your help!

    Karl

  4. #4
    Join Date
    Aug 2004
    Posts
    105

    Default hello

    Hello,
    Juergen can u explain the alternative option. We are using SLSB for business layer and (spring+hibernate (sometimes spring + jdbc)) for DAO layer and using EJB CMT for transaction management.
    The configuration i have is the following is it right?? Please tell me asap. And if not can u please paste the way it should be (We are using our own datasource not from spring).

    What i want to ask is should i use jta abstraction of spring or specify Hibernate transaction manager which delagtes to jta?

    <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
    <!--Application context definition for EMR Relase 1.0 maintained by Shoaib on Hibernate.-->
    <beans>
    <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.Pr opertyPlaceholderConfigurer">
    <property name="location"><value>jdbc.properties</value></property>
    </bean>

    <bean id="dataSource" class="org.springframework.jdbc.oracle.OracleOCICo nnectionPoolDataSource">
    <property name="driverType"><value>${jdbc.driverType}</value></property>
    <property name="tnsName"><value>${jdbc.tnsName}</value></property>
    <property name="username"><value>${jdbc.username}</value></property>
    <property name="password"><value>${jdbc.password}</value></property>
    <property name="connectionStrategy"><ref local="connectionStrategy" /></property>
    </bean>

    <bean id="connectionStrategy" class="org.springframework.jdbc.oracle.OracleOCICo nnectionThreadLocalStrategy" />

    <!-- Hibernate SessionFactory -->
    <bean id="sessionFactory" class="org.springframework.orm.hibernate.LocalSess ionFactoryBean">
    <property name="dataSource"><ref local="dataSource" /></property>
    <!-- Mapping Resources for Hibernate Session Factory (Specify the hbm.xml to be used here) -->
    <property name="mappingResources">
    <list>
    <value>com/sequelsys/common/model/scheduling/DailyRosterModel.hbm.xml</value>
    </list>
    </property>
    <property name="hibernateProperties">
    <props>
    <prop key="hibernate.dialect">net.sf.hibernate.dialect.O racle9Dialect</prop>
    <prop key="hibernate.transaction.factory_class">net.sf.h ibernate.transaction.JTATransactionFactory</prop>
    <prop key="hibernate.transaction.manager_lookup_class">n et.sf.hibernate.transaction.JBossTransactionManage rLookup</prop>
    <prop key="hibernate.jta.UserTransaction">java:comp/UserTransaction</prop>
    <prop key="hibernate.show_sql">true</prop>
    <prop key="hibernate.cglib.use_reflection_optimizer">tru e</prop>
    </props>
    </property>
    </bean>
    <!-- Transaction manager for a single Hibernate SessionFactory (alternative to JTA) -->
    <bean id="transactionManager" class="org.springframework.orm.hibernate.Hibernate TransactionManager">
    <property name="sessionFactory"><ref local="sessionFactory" /></property>
    </bean>
    <!-- Refereces of DAOs to be used by Session beans-->
    <bean id="practiceLocationDAO" class="com.sequelsys.server.common.dao.PracticeLoc ationDAO" autowire="byName" />
    </beans>

    Regards,
    Shoaib Akhtar
    Regards,
    Shoaib Akhtar

  5. #5
    Join Date
    Aug 2004
    Posts
    105

    Default Re:

    Hello,
    I want to add something when i replace the upper files lines with this one

    <property name="hibernateProperties">
    <props>
    <prop key="hibernate.dialect">net.sf.hibernate.dialect.O racle9Dialect</prop>
    <prop key="hibernate.show_sql">true</prop>
    <prop key="hibernate.cglib.use_reflection_optimizer">tru e</prop>
    </props>
    </property>
    </bean>
    <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTran sactionManager"/>


    i get following exceptions ( running jboss 3.2.3 , Oracle 9i, hibernate 2.1.6, Spring 1.1 rc 2)

    Caused by: org.springframework.beans.factory.BeanCreationExce ption: Error creating bean with name 'transactionManager' defined in class path resource [applicationContext-hibernate.xml]: Initialization of bean failed; nested exception is org.springframework.transaction.CannotCreateTransa ctionException: JTA UserTransaction is not available at JNDI location [java:comp/UserTransaction]; nested exception is javax.naming.NameNotFoundException: UserTransaction not bound


    Please help me asap because after reading yuor earlier post i think that we are using no transaction.
    Regards,
    Shoaib Akhtar

  6. #6
    Join Date
    Aug 2004
    Location
    New York
    Posts
    168

    Default Hibernate, OpenSessionInViewFilter, J2EE transaction manager

    To add to my previous response, I have been stepping through the getSession method of SessionFactoryUtils. It seems to me that when using a J2EE transaction manager, the open session is only found when a transaction status is active. Otherwise, a new session will always be opened and closed and you will get lazy initialization exceptions, which I am currently experiencing.

    Let me know if I am misunderstanding this method. Thanks again for your help!

    Karl

  7. #7
    Join Date
    Aug 2004
    Location
    Toronto, Canada
    Posts
    736

    Default

    Shoaib,

    I have personally used Spring with JBoss 3.2.3 and it works fine with JTATransactionManager. You may want to verify with the JNDI view (port of JBoss's JMX console) that the UserTransaction object is where it's supposed to be (java:comp/UserTransaction). That's the standard location, and it should be there, but something weird may be going on in your JBoss instance.

    Colin

  8. #8
    Join Date
    Aug 2004
    Location
    Toronto, Canada
    Posts
    736

    Default

    Karl,

    Using Spring's JTATransactionManager class vs. HibernateTransactionManager class should not really affect Session handling if the OpenSessionInViewFilter is in use with the older singleSession=true mode. If the filter is used like this, then the filter is creating the session and binding it, and any contained code lower down like HibernateTemplate, using the _same_ SessionFactory set of course, will simply use that session. If this is your config, I would verify via the logs that the filter is actually kicking in and creating the session, and than any Hibernate usage via the template is actually set to the same SessionFactory, so that it can realize a related Session is already bound.

    Now if you are using the filter in singleSession=false mode, then there should still not be any issues with switching from HibernateTranactionManager to JTATransactionManager, but you should realize that in this mode, with HibernateTransactionManager, that spring tm will automatically create and bind a session as soon as execution flows through it. JTATransactionManager on the other hand knows nothing about Hibernate sessioons, so the Session would only be created and bound on the first usage of a HibernateTempalte (or SessionFactoryUtils.getSession), with the allowCreate flag set to true (the default). The net effect is the same, but the time of creation of the session is different. If you want to get the exact same effect when using JTATrransactionManager as when using HibernateTransactionManager, you need to add in HibernateInterceptor into the transaction proxy, which will ensure that the session is also created when the JTA transaction is joined or created.

    Note also that your usage of Hibernate's TransactionManagerLookup is not needed generally, as Spring is hadling tx synchronization. In some JTA environments however you will get warnings on operations after a tx is complete, as the tx manage ris very restrictive and will complain even on a close call, and adding in the lookup will resolve this.

    Regards,
    Colin Sampaleanu
    SpringSource - http://www.springsource.com

  9. #9
    Join Date
    Aug 2004
    Location
    New York
    Posts
    168

    Default Hibernate, OpenSessionInViewFilter, J2EE transaction manager

    Hi Colin. Thanks for the response. To clarify I am using single session mode for my Open Session Filter. I actually stepped through the code through the eclipse remote debugger and saw that it was indeed hitting the following logic in OpenSessionInViewFilter:
    Code:
    if &#40;isSingleSession&#40;&#41;&#41; &#123;
    	logger.debug&#40;"Opening single Hibernate session in OpenSessionInViewFilter"&#41;;
    	session = getSession&#40;sessionFactory&#41;;
    	TransactionSynchronizationManager.bindResource&#40;sessionFactory, new SessionHolder&#40;session&#41;&#41;;
    &#125;
    I think the problem is occuring in this else block in SessionFactoryUtils:
    Code:
    else &#123;
    	TransactionManager jtaTm = getJtaTransactionManager&#40;sessionFactory, sessionHolder.getAnySession&#40;&#41;&#41;;
    	if &#40;jtaTm != null&#41; &#123;
    		try &#123;
    			int jtaStatus = jtaTm.getStatus&#40;&#41;;
    			if &#40;jtaStatus == Status.STATUS_ACTIVE || jtaStatus == Status.STATUS_MARKED_ROLLBACK&#41; &#123;
    				Session session = sessionHolder.getSession&#40;jtaTm.getTransaction&#40;&#41;&#41;;
    				if &#40;session != null&#41; &#123;
    					return session;
    				&#125;
    			&#125;
    		&#125; catch &#40;SystemException ex&#41; &#123;
    			throw new DataAccessResourceFailureException&#40;"Could not check JTA transaction", ex&#41;;
    		&#125;
    	&#125;  else &#123;
    		return sessionHolder.getSession&#40;&#41;;
    	&#125;
    &#125;
    When I step through the code, it finds the jta Transaction Manager and checks the jts status. The jta status comes back inactive and the open session is not returned. After exiting out of the else block, the rest of the method seems to be concerned with creating a new session which will eventually cause my application to throw LazyInitialization exceptions as this session will be closed before rendering the view. It seems to me like the session will only be returned if a Transaction is active.

    I believe I have traced it down to the specific problem area but I am not sure how to fix this without modifying the spring code. Thanks again for your help.

    Karl

  10. #10
    Join Date
    Aug 2004
    Location
    Toronto, Canada
    Posts
    736

    Default

    Actually, you are going down a false path. As far as I can tell, you are not in a transaction. Normally what would happen then is that you would get a session created out fo transaction (if allowCreate=true) or else not get any session at all (with an exception), if allowCreate=false. But because you have set the JTATransactionManager, Spring instead tries to use that as a means to associate a session with just the JTA transaction. This is meant for CMT situations, with no Spring transaction transaction manager involved at all, where spring can bind the Hibernate session to the CMT transaction.

    Check your transaction proxy definition. I can almost guarantee that you are not intercepting properly. The log should show if you are actually entering into a transaction, higher up...

    Regards,
    Colin Sampaleanu
    SpringSource - http://www.springsource.com

Similar Threads

  1. HibernateTemplate and transactions
    By Simon Brunning in forum Data
    Replies: 4
    Last Post: Mar 9th, 2009, 12:37 AM
  2. JDO Transactions and JUnit testing
    By markds75 in forum Data
    Replies: 2
    Last Post: Sep 17th, 2005, 01:46 AM
  3. Replies: 1
    Last Post: Mar 23rd, 2005, 05:32 AM
  4. Replies: 4
    Last Post: Mar 15th, 2005, 05:50 AM
  5. Nested transactions
    By diegum in forum Data
    Replies: 1
    Last Post: Aug 30th, 2004, 10:57 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •