Results 1 to 3 of 3

Thread: HibernateTransaction and IllegalTransactionState Exception.

  1. #1
    Join Date
    May 2005
    Posts
    4

    Default HibernateTransaction and IllegalTransactionState Exception.

    Hi,

    I am trying to write a base class for integration testing. Unfortunately I can't extend the AbstractTransactionalSpringContextTest because I need to extend MockStrutsTestCase. So I decided to include the functionality in a base class which is essentially the same as AbstractTransactionalSpringContextTest.

    I want to be able to provide a 'hibernateTemplate' to specific implementations to use for setup of Integration testing. In this manner I can setup the database state, run the test case and then roll-back the transaction within the base class.

    I keep getting an IllegalTransactionStateException with the message
    Pre-bound JDBC connection found - HibernateTransactionManager does not support running within DataSourceTransactionManager if told to manage the DataSource itself. It is recommended to use a single HibernateTransactionManager for all transactions on a single DataSource, no matter whether Hibernate or JDBC access.
    I've looked at the code and this exception is called if
    if (getDataSource() != null && TransactionSynchronizationManager.hasResource(getD ataSource())) {
    I am very confused by this error message and I was hoping someone could tell me what I am doing wrong. My appContext is
    Code:
    	<!-- Local DataSource that works in any environment -->
    	<bean id="myDataSource" name="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    		<property name="driverClassName"><value>$&#123;jdbc.driverClassName&#125;</value></property>
    		<property name="url"><value>$&#123;jdbc.url&#125;</value></property>
    		<property name="username"><value>$&#123;jdbc.username&#125;</value></property>
    		<property name="password"><value>$&#123;jdbc.password&#125;</value></property>
    	</bean>
    	<bean id="mySessionFactory"
    		class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
    		<property name="dataSource">
    			<ref bean="myDataSource"/>
    		</property>
    		<property name="mappingResources">
    			<list>
    				<value>
    					program.hbm.xml</value>
    				<value>
    					budgetallocation.hbm.xml</value>
    				<value>
    					bonusallocation.hbm.xml</value>
    				<value>
    					programguideline.hbm.xml</value>
    				<value>
    					notification.hbm.xml</value>
    			</list>
    		</property>
    		<property name="hibernateProperties">
    			<props>
    				<prop key="hibernate.dialect">$&#123;hibernate.dialect&#125;</prop>
    				<prop key="hibernate.query.substitutions">true=1 false=0</prop>
    				<prop key="hibernate.show_sql">true</prop>
    			</props>
    		</property>
    	</bean>
    	
    	<bean id="transactionManager"
    		class="org.springframework.orm.hibernate.HibernateTransactionManager">
    		<property name="sessionFactory">
    			<ref local="mySessionFactory"/>
    		</property>
    	</bean>
    	
    		
    	<bean id="hibernateTemplate"
    		class="org.springframework.orm.hibernate.HibernateTemplate"
    		>
    		<property name="sessionFactory">
    			<ref local="mySessionFactory"/>
    		</property>
    	</bean>
    I am using Declared Transactions using TransactionProxy when wiring up my real transactions.

    Code:
    	<bean id="programInfo"
    	class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
    		<property name="transactionManager">
    			<ref bean="transactionManager"/>
    		</property>
    		<property name="target">
    			<bean id="programInfoTarget"
    				class="ProgramInfoDAO">
    				<property name="sessionFactory">
    					<ref bean="mySessionFactory"/>
    				</property>
    			</bean>
    		</property>
    		<property name="transactionAttributes">
    			<props>
    				<prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
    				<prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
    				<prop key="load*">PROPAGATION_NESTED,readOnly</prop>
    				<prop key="store*">PROPAGATION_REQUIRED</prop>
    			</props>
    		</property>
    	</bean>
    My BaseTestClass does the following:

    Code:
    		this.transactionStatus = transactionManager.getTransaction&#40;new DefaultTransactionDefinition&#40;&#41;&#41;;
    		&#40;&#40;AbstractPlatformTransactionManager&#41;transactionManager&#41;.setNestedTransactionAllowed&#40;true&#41;;
    
    		hibernateTemplate = &#40;HibernateTemplate&#41;applicationContext.getBean&#40;"hibernateTemplate" &#41;;
    		logger.info&#40;"Began transaction&#58; transaction manager=&#91;" + this.transactionManager +
    		    "&#93;; defaultCommit=" + this.complete&#41;;
    Since HibernateTransactionManager is managing everything, I thought everything work ok. Can someone help?

    Take Care
    Jason

  2. #2
    Join Date
    May 2005
    Posts
    4

    Default Solved.. I think.

    For the benefit of those who may be interested I've managed to narrow the problem down to how MockStrutsTestCase works. I forgot that Struts will initialize it's own copy of ApplicationContext.

    This means a whole new set of singletons. Transaction management uses ThreadLocal to store the context. The new singletons are not aware of this and try to initialize a new Transaction manager. The hibernate sees the old transaction state on ThreadLocal and raises an exception.

    This looks like it's the reason for getting the error. Can somebody more adept at Spring confirm this theory?

    Can transaction managers (specfically Hibernate) exist accross multiple BeanFactories/ApplicationContexts?

    Take Care
    Jason

  3. #3
    Join Date
    Jan 2005
    Location
    Bucharest, Romania
    Posts
    5,403

    Default

    Can transaction managers (specfically Hibernate) exist accross multiple BeanFactories/ApplicationContexts?
    I think not but I might be mistaken. However, I think you are trying to solve the wrong problem .
    Try to get a hold of the TransactionManager/AppContext used by MockStrutsTestCase especially if you are extending it. It appears to me that you are thinking against the TestCase...
    Costin Leau
    SpringSource - http://www.SpringSource.com- Spring Training, Consulting, and Support - "From the Source"
    http://twitter.com/costinl
    Please use [ c o d e ] [ / c o d e ] tags

Similar Threads

  1. Replies: 3
    Last Post: Oct 5th, 2005, 08:39 AM
  2. Context initialization failed
    By kanonmicke in forum Container
    Replies: 7
    Last Post: Sep 29th, 2005, 12:35 AM
  3. Odd behaviour when injecting TransactionTemplate
    By damon311 in forum Container
    Replies: 3
    Last Post: Jul 23rd, 2005, 11:21 AM
  4. Replies: 0
    Last Post: Jul 11th, 2005, 05:49 PM
  5. Replies: 3
    Last Post: Nov 8th, 2004, 07:30 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
  •