Results 1 to 7 of 7

Thread: Spring JDBC not rolling back

  1. #1
    Join Date
    May 2012
    Posts
    4

    Default Spring JDBC not rolling back

    I have all the annotations correct and even see the output log state Spring is rolling back the transaction; however, the Oracle table is not rolled back.

    Here is the class:


    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(locations = { "classpath:dbConnection-context.xml" })
    @TransactionConfiguration(defaultRollback = true)
    @Transactional
    public class JUnitTestCase {

    @Test
    public void testInsert() {
    jdbcForumDAOImpl.insertRegistration("Tom");
    }

    Here is the log output:


    00:52:15.484 [main] DEBUG o.s.t.c.t.TransactionalTestExecutionListener - No method-level @Rollback override: using default rollback [true] for test context [[TestContext@56de56de testClass = JUnitTestCase, testInstance = com.coineta.test.JUnitTestCase@7a2a7a2a, testMethod = testInsert@JUnitTestCase, testException = [null], mergedContextConfiguration = [MergedContextConfiguration@6cde6cde testClass = JUnitTestCase, locations = '{classpath:dbConnection-context.xml}', classes = '{}', activeProfiles = '{}', contextLoader = 'org.springframework.test.context.support.Delegati ngSmartContextLoader']]]
    00:52:15.484 [main] DEBUG o.s.j.d.DataSourceTransactionManager - Initiating transaction rollback
    00:52:15.484 [main] DEBUG o.s.j.d.DataSourceTransactionManager - Rolling back JDBC transaction on Connection [oracle.jdbc.driver.T4CConnection@53485348]
    00:52:15.484 [main] DEBUG o.s.j.d.DataSourceTransactionManager - Releasing JDBC Connection [oracle.jdbc.driver.T4CConnection@53485348] after transaction
    00:52:15.484 [main] DEBUG o.s.jdbc.datasource.DataSourceUtils - Returning JDBC Connection to DataSource
    00:52:15.500 [main] INFO o.s.t.c.t.TransactionalTestExecutionListener - Rolled back transaction after test execution for test context [[TestContext@56de56de testClass = JUnitTestCase, testInstance = com.coineta.test.JUnitTestCase@7a2a7a2a, testMethod = testInsert@JUnitTestCase, testException = [null], mergedContextConfiguration = [MergedContextConfiguration@6cde6cde testClass = JUnitTestCase, locations = '{classpath:dbConnection-context.xml}', classes = '{}', activeProfiles = '{}', contextLoader = 'org.springframework.test.context.support.Delegati ngSmartContextLoader']]]
    00:52:15.500 [main] DEBUG o.s.t.c.t.TransactionalTestExecutionListener - Executing @AfterTransaction method [public void com.coineta.test.JUnitTestCase.afterTransaction()] for test context [[TestContext@56de56de testClass = JUnitTestCase, testInstance = com.coineta.test.JUnitTestCase@7a2a7a2a, testMethod = testInsert@JUnitTestCase, testException = [null], mergedContextConfiguration = [MergedContextConfiguration@6cde6cde testClass = JUnitTestCase, locations = '{classpath:dbConnection-context.xml}', classes = '{}', activeProfiles = '{}', contextLoader = 'org.springframework.test.context.support.Delegati ngSmartContextLoader']]]
    00:52:15.500 [main] DEBUG o.s.j.d.DriverManagerDataSource - Creating new JDBC DriverManager Connection to [jdbc:oracle:thin:@192.168.2.113:1521:orcl]
    00:52:15.531 [main] DEBUG o.s.t.c.s.DirtiesContextTestExecutionListener - After test method: context [[TestContext@56de56de testClass = JUnitTestCase, testInstance = com.coineta.test.JUnitTestCase@7a2a7a2a, testMethod = testInsert@JUnitTestCase, testException = [null], mergedContextConfiguration = [MergedContextConfiguration@6cde6cde testClass = JUnitTestCase, locations = '{classpath:dbConnection-context.xml}', classes = '{}', activeProfiles = '{}', contextLoader = 'org.springframework.test.context.support.Delegati ngSmartContextLoader']]], class dirties context [false], class mode [null], method dirties context [false].
    00:52:15.531 [main] DEBUG o.s.t.c.s.DirtiesContextTestExecutionListener - After test class: context [[TestContext@56de56de testClass = JUnitTestCase, testInstance = [null], testMethod = [null], testException = [null], mergedContextConfiguration = [MergedContextConfiguration@6cde6cde testClass = JUnitTestCase, locations = '{classpath:dbConnection-context.xml}', classes = '{}', activeProfiles = '{}', contextLoader = 'org.springframework.test.context.support.Delegati ngSmartContextLoader']]], dirtiesContext [false].
    00:52:15.531 [Thread-4] INFO o.s.c.s.GenericApplicationContext - Closing org.springframework.context.support.GenericApplica tionContext@255e255e: startup date [Mon May 07 00:52:12 EDT 2012]; root of context hierarchy
    00:52:15.531 [Thread-4] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Returning cached instance of singleton bean 'lifecycleProcessor'
    00:52:15.531 [Thread-4] INFO o.s.b.f.s.DefaultListableBeanFactory - Destroying singletons in org.springframework.beans.factory.support.DefaultL istableBeanFactory@71b871b8: defining beans [jdbcDataSource,transactionManager,forumDAO,altOrde rDAO,orderDAO,authenticationDAO,org.springframewor k.context.annotation.internalConfigurationAnnotati onProcessor,org.springframework.context.annotation .internalAutowiredAnnotationProcessor,org.springfr amework.context.annotation.internalRequiredAnnotat ionProcessor,org.springframework.context.annotatio n.ConfigurationClassPostProcessor$ImportAwareBeanP ostProcessor#0]; root of factory hierarchy

  2. #2
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,625

    Default

    Please use [ code][/code ] tags when posting code/xml/stacktraces.

    Post the code for your dao and some configuration.
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

  3. #3
    Join Date
    May 2012
    Posts
    4

    Default Entering DAO and configuration files

    Quote Originally Posted by Marten Deinum View Post
    Please use [ code][/code ] tags when posting code/xml/stacktraces.

    Post the code for your dao and some configuration.
    Thanks for responding..

    Configuration file below:
    [code]
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:tx="http://www.springframework.org/schema/tx" xmlns:p="http://www.springframework.org/schema/p"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">

    <bean id="jdbcDataSource"
    class="org.springframework.jdbc.datasource.DriverM anagerDataSource"
    p:driverClassName="oracle.jdbc.xa.client.OracleXAD ataSource" p:url="jdbc:oracle:thin:@192.168.2.113:1521:orcl"
    p:username="xxxxx" p:password="xxxxx />


    <bean id="transactionManager"
    class="org.springframework.jdbc.datasource.DataSou rceTransactionManager">
    <property name="dataSource" ref="jdbcDataSource" />
    </bean>

    <bean id="forumDAO" class="com.web.test.JDBCForumDAOImpl">
    <property name="dataSource" ref="jdbcDataSource" />
    </bean>
    </beans>
    [/code ]

    DAO code below:
    Code:
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    
    import javax.sql.DataSource;
    
    public class JDBCForumDAOImpl {
    
    	private DataSource dataSource;
    
    	public void setDataSource(DataSource dataSource) {
    		this.dataSource = dataSource;
    	}
    
    
    	public String insertRegistration(String userName) {
    		Connection connection = null;
    		Statement statement = null;
    		ResultSet resultSet = null;
    		try {
    			/**
    			 * Open the connection
    			 */
    			connection = dataSource.getConnection();
    			/**
    			 * Prepare the statement
    			 */
    			statement = connection.createStatement();
    
    			String sql = "INSERT INTO Registration " + "VALUES ('" + userName +"')";
    			statement.executeUpdate(sql);
    
    
    		} catch (SQLException e) {
    			/**
    			 * Handle any exception
    			 */
    			e.printStackTrace();
    		} finally {
    			try {
    				/**
    				 * Close the resultSet
    				 */
    				if (resultSet != null) {
    					resultSet.close();
    				}
    				/**
    				 * Close the connection
    				 */
    				if (connection != null) {
    					connection.close();
    				}
    			} catch (SQLException e) {
    				/**
    				 * Handle any exception
    				 */
    				e.printStackTrace();
    			}
    		}
    		return null;
    	}
    
    
    }

  4. #4
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,625

    Default

    And the rollback should happen why?! You are doing your own connection management and executing queries directly without using spring or tapping into spring.

    Use the JdbcTemplate instead of the datasource directly saves you a lot of ugly code. Also you code is flawed (security wise) NEVER NEVER NEVER use string concat to create a query with parameters. Use placeholders (?) for that. Your current code makes it possible to do sql injection...
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

  5. #5
    Join Date
    May 2012
    Posts
    4

    Default

    Thanks for responding..

    The example that was posted is a very simple example via Statement. Why start with a difficult example? Once the Spring Framwork is working correctly, I'll make it Judy proof by using prepared statements..

    Executing queries without tapping into Spring? The objective is to test the DAO without change anything, for once the datasource object is set, the DAO does execute the query successfully as is. Does the DAO need to import Spring resources for it to work sucessful? What happens if I want to test Legacy JDBC code without changing anything on the DAO side? Knowing this, I do want to use the jdbcTemplete framework.

    Managing my own connection? Spring is being used(the XML file is being read to retrieve data source connection information) to bind/create the connection since the queries work, correct?

    Please see the link below. I do not believe is uses JdbcTemplete and it's very similar to the code posted:

    http://www.mkyong.com/spring/maven-spring-jdbc-example/

  6. #6
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,625

    Default

    Managing my own connection? Spring is being used(the XML file is being read to retrieve data source connection information) to bind/create the connection since the queries work, correct?
    Yes you are managing your own connection.. You are calling getConnection and that ALWAYS gives you a NEW connection because, as I stated, you aren't using spring.

    The objective is to test the DAO without change anything, for once the datasource object is set, the DAO does execute the query successfully as is. Does the DAO need to import Spring resources for it to work sucessful? What happens if I want to test Legacy JDBC code without changing anything on the DAO side?
    If you want to test legacy code you need to wrap your datasource in a TransactionAwareDataSourceProxy as explained in the reference guide. This will wrap the datasource and connections and taps into springs transaction management.

    Please see the link below. I do not believe is uses JdbcTemplete and it's very similar to the code posted:
    The code is similair BUT is still doesn't use spring to manage transactions and resources and the latter is the problem. You want to use spring to manage your transactions but next don't take an effort to make this possible (by either using JdbcTemplate or using the TransactionAwareDataSourceProxy).

    The example that was posted is a very simple example via Statement. Why start with a difficult example? Once the Spring Framwork is working correctly, I'll make it Judy proof by using prepared statements..
    I understand it is a sample the problem with this kind of code is that it never gets changed because "it simply works" and as such remains in production with all security risks at hand. You don't want to know how many demo or proof-of-concept applications are in production because 'well it works isn't it'....
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

  7. #7
    Join Date
    May 2012
    Posts
    4

    Default

    Thanks for responding Marten...

    ok..I reviewed javadoc and it looks as though the only change is to the configuration file; it needs to include a delcaration for TransactionAwareDataSourceProxy to wrap the current datasource conection. It does this by referencing the existing datasource declaration id(datasource). The DAO should not have to change since the dataSource connection within the DAO will be wrapped by TransactionAwareDataSourceProxy. Now Spring should be controlling the transaction and a Rollback should be possible?

    Code:
    <bean id="jdbcDataSource" class="org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy">
         <constructor-arg ref="dataSource"/>
    </bean>
    
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"
           p:driverClassName="oracle.jdbc.xa.client.OracleXADataSource" p:url="jdbc:oracle:thin:@192.168.2.113:1521:orcl"
           p:username="xxxxx" p:password="xxxxx />

Posting Permissions

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