Announcement Announcement Module
Collapse
No announcement yet.
Configure JTA (JOTM) to share hibernate and jdbc connection? Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Configure JTA (JOTM) to share hibernate and jdbc connection?

    Dear all,

    Is it possible use JTA(JOTM) to let HibernateTemplate and JdbcTemplate share the same database connection ? I have tried to configure JtaTransactionManager with HibernateIntercetor, but it does not work... below is my test configuration:

    applicationContext.xml
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
        "http&#58;//www.springframework.org/dtd/spring-beans.dtd">
    
    <beans>
    	<bean id="jotm"
    		class="org.springframework.transaction.jta.JotmFactoryBean" />
    
    	<bean id="innerDataSource"
    		class="org.enhydra.jdbc.standard.StandardXADataSource"
    		destroy-method="shutdown">
    		<property name="transactionManager">
    			<ref local="jotm" />
    		</property>
    		<property name="driverName">
    			<value>oracle.jdbc.driver.OracleDriver</value>
    		</property>
    		<property name="url">
    			<value>
    				jdbc&#58;oracle&#58;thin&#58;@abcd.bioinfo&#58;1521&#58;ABCD
    			</value>
    		</property>
    	</bean>
    
    	<bean id="dataSource"
    		class="org.enhydra.jdbc.pool.StandardXAPoolDataSource"
    		destroy-method="shutdown">
    		<property name="dataSource">
    			<ref local="innerDataSource" />
    		</property>
    		<property name="user">
    			<value>abcd</value>
    		</property>
    		<property name="password">
    			<value>abcd</value>
    		</property>
    		<property name="maxSize">
    			<value>30</value>
    		</property>
    	</bean>
    
    	<bean id="sessionFactory"
    		class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    		<property name="dataSource">
    			<ref bean="dataSource" />
    		</property>
    		<property name="mappingDirectoryLocations">
    			<list>
    				<value>classpath&#58;/antar/</value>
    			</list>
    		</property>
    		<property name="hibernateProperties">
    			<props>
    				<prop key="hibernate.show_sql">true</prop>
    				<prop key="hibernate.dialect">
    					org.hibernate.dialect.Oracle9Dialect
    				</prop>
    			</props>
    		</property>
    		<property name="jtaTransactionManager">
    			<ref bean="jotm" />
    		</property>
    	</bean>
    
    	<bean id="jdbcTemplate"
    		class="org.springframework.jdbc.core.JdbcTemplate">
    		<property name="dataSource">
    			<ref local="dataSource" />
    		</property>
    	</bean>
    
    	<bean id="hibernateTemplate"
    		class="org.springframework.orm.hibernate3.HibernateTemplate">
    		<property name="sessionFactory">
    			<ref bean="sessionFactory" />
    		</property>
    	</bean>
    
    
    	<bean id="transactionManager"
    		class="org.springframework.transaction.jta.JtaTransactionManager">
    		<property name="userTransaction">
    			<ref local="jotm" />
    		</property>
    	</bean>
    
    	<bean id="checkSameConnection"
    		class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
    		<property name="transactionManager">
    			<ref local="transactionManager" />
    		</property>
    		<property name="target">
    			<bean class="antar.config.CheckSameConnectionImpl">
    				<property name="hibernateTemplate">
    					<ref bean="hibernateTemplate" />
    				</property>
    				<property name="jdbcTemplate">
    					<ref bean="jdbcTemplate" />
    				</property>
    			</bean>
    		</property>
    		<property name="transactionAttributes">
    			<props>
    				<prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
    			</props>
    		</property>
    		<property name="postInterceptors">
    			<list>
    				<bean
    					class="org.springframework.orm.hibernate3.HibernateInterceptor">
    					<property name="sessionFactory">
    						<ref bean="sessionFactory" />
    					</property>
    				</bean>
    			</list>
    		</property>
    	</bean>
    </beans>
    CheckSameConnection and CheckSameConnectionImpl are simple
    classes and wrapped by transaction. CheckSameConnectionImpl inject HibernateTemplate and JdbcTemplate to check whether the connection is shared.
    Code:
    public interface CheckSameConnection &#123;
        public void doTransaction&#40;&#41;;
    &#125;
    
    
    public class CheckSameConnectionImpl implements CheckSameConnection &#123;
    
        private HibernateTemplate hibernateTemplate;
    
        private JdbcTemplate jdbcTemplate;
    
        public void doTransaction&#40;&#41; &#123;
    
            final XAPoolNativeJdbcExtractor extractor = new XAPoolNativeJdbcExtractor&#40;&#41; ;
    
            System.out.println&#40;"begin... "&#41;;
    
            hibernateTemplate.execute&#40;new HibernateCallback&#40;&#41; &#123;
                public Object doInHibernate&#40;final Session session&#41;
                        throws HibernateException, SQLException &#123;
    
                    final Connection connFromHibernate = session.connection&#40;&#41; ;
                    
                    jdbcTemplate.execute&#40;new ConnectionCallback&#40;&#41; &#123;
                        public Object doInConnection&#40;final Connection connFromJdbc&#41;
                                throws SQLException, DataAccessException &#123;
                            
                            Connection ch = extractor.getNativeConnection&#40;connFromHibernate&#41; ;
                            Connection cj = extractor.getNativeConnection&#40;connFromJdbc&#41; ;
    
                            if&#40; cj== ch&#41; &#123;
                                System.out.println&#40;"same connection"&#41;;
                            &#125; else &#123;
                                System.err.println&#40;"not same connection&#58;" + cj +" != " + ch&#41;;
                            &#125;
                            
                            return null;
                        &#125;
                    &#125;&#41;;
    
                    return null;
                &#125;
            &#125;&#41;;
            System.out.println&#40;"done..."&#41;;
        &#125;
    
    &#125;
    finally, a simple test case to invoke a transaction wrapped checkSameConnection bean:
    Code:
    public class HibernateJDBCConnectionTest extends
            AbstractDependencyInjectionSpringContextTests &#123;
        protected String&#91;&#93; getConfigLocations&#40;&#41; &#123;
            return new String&#91;&#93; &#123;"/applicationContext-jta.xml"&#125; ; 
        &#125;
        public void testSameConnectionWithSameTransactionManager&#40;&#41; &#123;
            CheckSameConnection csc = &#40;CheckSameConnection&#41; applicationContext
                    .getBean&#40;"checkSameConnection"&#41;;
    
            csc.doTransaction&#40;&#41;;
        &#125;
    &#125;
    and the debug output is
    Code:
    DEBUG AbstractPlatformTransactionManager - Using transaction object &#91;org.springframework.transaction.jta.JtaTransactionObject@2b3483&#93;
    DEBUG AbstractPlatformTransactionManager - Creating new transaction
    DEBUG JtaTransactionManager - Beginning JTA transaction
    DEBUG TransactionSynchronizationManager - Initializing transaction synchronization
    DEBUG SessionFactoryUtils - Opening Hibernate session
    DEBUG SessionFactoryUtils - Registering Spring transaction synchronization for new Hibernate session
    DEBUG TransactionSynchronizationManager - Bound value &#91;org.springframework.orm.hibernate3.SessionHolder@46c21b&#93; for key &#91;org.hibernate.impl.SessionFactoryImpl@c701cb&#93; to thread &#91;main&#93;
    DEBUG HibernateInterceptor - Found thread-bound session for Hibernate interceptor
    
    begin... 
    
    DEBUG TransactionSynchronizationManager - Retrieved value &#91;org.springframework.orm.hibernate3.SessionHolder@46c21b&#93; for key &#91;org.hibernate.impl.SessionFactoryImpl@c701cb&#93; bound to thread &#91;main&#93;
    DEBUG TransactionSynchronizationManager - Retrieved value &#91;org.springframework.orm.hibernate3.SessionHolder@46c21b&#93; for key &#91;org.hibernate.impl.SessionFactoryImpl@c701cb&#93; bound to thread &#91;main&#93;
    DEBUG TransactionSynchronizationManager - Bound value &#91;org.springframework.jdbc.datasource.ConnectionHolder@59e40&#93; for key &#91;StandardXAPoolDataSource&#58;  ... **cut**
    
    not same connection&#58;oracle.jdbc.driver.T4CConnection@74641 != oracle.jdbc.driver.T4CConnection@d59861
    
    DEBUG TransactionSynchronizationManager - Retrieved value &#91;org.springframework.jdbc.datasource.ConnectionHolder@59e40&#93; for key &#91;StandardXAPoolDataSource&#58; ... **cut**
    DEBUG TransactionSynchronizationManager - Retrieved value &#91;org.springframework.orm.hibernate3.SessionHolder@46c21b&#93; for key &#91;org.hibernate.impl.SessionFactoryImpl@c701cb&#93; bound to thread &#91;main&#93;
    
    done...
    
    DEBUG HibernateInterceptor - Not closing pre-bound Hibernate session after interceptor
    DEBUG AbstractPlatformTransactionManager - Triggering beforeCommit synchronization
    DEBUG AbstractPlatformTransactionManager - Triggering beforeCompletion synchronization
    DEBUG TransactionSynchronizationManager - Removed value &#91;org.springframework.orm.hibernate3.SessionHolder@46c21b&#93; for key &#91;org.hibernate.impl.SessionFactoryImpl@c701cb&#93; from thread &#91;main&#93;
    DEBUG SessionFactoryUtils - Closing Hibernate session
    DEBUG TransactionSynchronizationManager - Removed value &#91;org.springframework.jdbc.datasource.ConnectionHolder@59e40&#93; for key &#91;StandardXAPoolDataSource&#58;  ... **cut**
    DEBUG AbstractPlatformTransactionManager - Initiating transaction commit
    DEBUG JtaTransactionManager - Committing JTA transaction
    DEBUG AbstractPlatformTransactionManager - Triggering afterCompletion synchronization
    DEBUG TransactionSynchronizationManager - Clearing transaction synchronization
    the result shows that TransactionManager and HibernateInterceptor work correctly, however, the connection used by HibernateTemplate is not the same as the one used by JdbcTemplate...

    Do I missing something ?

    ps. Spring - 1.2rc1
    Hibernate - 3.0rc1
Working...
X