Announcement Announcement Module
Collapse
No announcement yet.
Simple Hibernate Transaction Rollback test Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Simple Hibernate Transaction Rollback test

    hi,

    I'm kinda new with spring and I wanted to try out the hibernate transactionmanager. The scenario is simple enough: I start a transaction (programmatically), add a Project to the DB and in the same transaction I add a User. The latter will throw (as intended) an exception because one of it's mandatory fields is null. In the catch-block I do a rollback and I would expect the insert of the project to have been rolled back. However this is not the case; the project is added to the DB and is not removed.

    Source AbstractService;
    Code:
    public class AbstractService
    {
    	protected PlatformTransactionManager transactionManager = null;
    
    	public void setTransactionManager(PlatformTransactionManager transactionManager)
    	{
    		this.transactionManager = transactionManager;
    	}
    
    	protected TransactionStatus startNewTransaction()
    	{
    		TransactionStatus status = null;
    		DefaultTransactionDefinition definition = new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
    		if (transactionManager != null)
    		{
    			status = transactionManager.getTransaction(definition);
    		}
    		return status;
    	}
    }
    ProjectServiceImpl extends AbstractService:
    Source createProject (= the test method)
    Code:
    	public void createProject(Project project, User creator)
    	{
    		TransactionStatus status = startNewTransaction();
    
    		try
    		{
    			project.setVersion(new Integer(1));
    
    			projectDAO.save(project); //does a simple hibernatetemplate.save
    
    			User u = new User();
    
    			projectDAO.save(u);
    
    			transactionManager.commit(status);
    
    		}
    		catch (Exception e)
    		{
    			transactionManager.rollback(status);
    		}
    
    	}
    declaration of transactionmanager:
    Code:
    	<bean id="transactionManager"
    		class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    		<property name="sessionFactory">
    			<ref bean="sessionFactory" />
    		</property>
    	</bean>
    I hope someone can help me out; been struggling way too long on this.

    Stijn

  • #2
    Can you post the rest of the config file ?

    Comment


    • #3
      As Andrei said it would be useful to see the configuration and also the log file contents. I would have a look at TransactionTemplate though.
      http://www.springframework.org/docs/...n-programmatic
      Last edited by karldmoore; Aug 29th, 2007, 11:28 AM.

      Comment


      • #4
        hi,

        tx for your interest.
        Actualy I already tried TransactionTemplate but with the same result :-(. Before that I tried the declerative approach but also no go.

        The 'full' config:
        Code:
        <beans>
        	<bean name="projectDAO" class="com.laco.planningtool.dao.ProjectDAOImpl"
        		autowire="byName" />
        
        	<bean name="projectService"
        		class="com.laco.planningtool.service.ProjectServiceImpl">
        		<property name="projectDAO" ref="projectDAO" />
        		<property name="transactionManager" ref="transactionManager" />
        	</bean>
        
        	<bean name="userDAO" class="com.laco.planningtool.dao.UserDAOImpl" autowire="byName" />
        
        	<bean name="userService" class="com.laco.planningtool.service.UserServiceImpl">
        		<property name="userDAO" ref="userDAO" />
        	</bean>
        
        	<bean name="resourceDAO" class="com.laco.planningtool.dao.ResourceDAOImpl"
        		autowire="byName" />
        
        	<bean name="resourceService"
        		class="com.laco.planningtool.service.ResourceServiceImpl">
        		<property name="resourceDAO" ref="resourceDAO" />
        	</bean>
        
        	<bean id="transactionManager"
        		class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        		<property name="sessionFactory">
        			<ref bean="sessionFactory" />
        		</property>
        	</bean>
        </beans>
        tx again,
        Stijn

        Comment


        • #5
          The configuration looks ok to me.
          Do you have multiple session factories in your config ? What properties do your daos have ?
          Try performing a test by manual setting daos' properties.

          Comment


          • #6
            I don't see the dataSource or the sessionFactory. Also, what database are you using?

            Comment


            • #7
              the dao only has one property and that's the hibernatetemplate so I don't think that's related?

              Comment


              • #8
                It would be useful to see the information Thomas asked for. That would probably be the easiest way to get the problem sorted. It would also be useful to see what the DEBUG logging says when the rollback should occur.
                Last edited by karldmoore; Aug 29th, 2007, 11:28 AM.

                Comment


                • #9
                  Oh, they're definitely related, There is a chain of dependencies: transactionManager -> sessionFactory -> dataSource -> database and if something is not configured right or your database doesn't support transactions, then it just won't work.

                  Also, add this to your log4j.properties:
                  Code:
                  log4j.logger.org.springframework.transaction=DEBUG
                  Then post your logging output.

                  Comment


                  • #10
                    sorry, I looked over Thomas's post:

                    The config for datasource & such:
                    Code:
                    <beans>
                    
                    	<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
                    		<property name="url" value="jdbc:mysql://localhost:3306/fod_test" />
                    		<property name="driverClassName" value="org.gjt.mm.mysql.Driver" />
                    		<property name="username" value="root" />
                    	</bean>
                    
                    	<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
                    		<property name="dataSource" ref="dataSource" />
                    		<property name="hibernateProperties">
                    			<props>
                    				<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
                    				<prop key="hibernate.hbm2ddl.auto">create</prop>
                    				<prop key="hibernate.show_sql">true</prop>
                    				<prop key="hibernate.format_sql">true</prop>
                    			</props>
                    		</property>
                    		<property name="mappingDirectoryLocations">
                    			<list>
                    				<value>classpath:/com/laco/planningtool</value>
                    			</list>
                    		</property>
                    	</bean>
                    	<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
                    		<property name="sessionFactory" ref="sessionFactory" />
                    	</bean>
                    
                    </beans>
                    I added the line log4j.logger.org.springframework.transaction=DEBUG to the log4j properties and here is the output:
                    Code:
                    30/06 10:35:35: INFO - org.springframework.orm.hibernate3.HibernateTransactionManager  - Using DataSource [[email protected]3c] of Hibernate SessionFactory for HibernateTransactionManager
                    30/06 10:35:35: DEBUG - org.springframework.transaction.support.TransactionSynchronizationManager  - Bound value [org.springframework.orm.hibernate3.SessionHolder@1d381d2] for key [org.hibernate.impl.SessionFactoryImpl@f01771] to thread [main]
                    30/06 10:35:35: DEBUG - org.springframework.transaction.support.TransactionSynchronizationManager  - Retrieved value [org.springframework.orm.hibernate3.SessionHolder@1d381d2] for key [org.hibernate.impl.SessionFactoryImpl@f01771] bound to thread [main]
                    30/06 10:35:35: DEBUG - org.springframework.transaction.support.TransactionSynchronizationManager  - Retrieved value [org.springframework.orm.hibernate3.SessionHolder@1d381d2] for key [org.hibernate.impl.SessionFactoryImpl@f01771] bound to thread [main]
                    Hibernate: select user0_.USER_ID as USER1_0_, user0_.FIRST_NAME as FIRST2_29_0_, user0_.email as email29_0_, user0_.SUR_NAME as SUR4_29_0_, user0_.function as function29_0_, user0_.mobile as mobile29_0_, user0_.password as password29_0_, user0_.phone as phone29_0_ from USER user0_ where user0_.USER_ID=?
                    30/06 10:35:35: INFO - org.springframework.jdbc.datasource.JdbcTransactionObjectSupport  - JDBC 3.0 Savepoint class is available
                    30/06 10:35:35: DEBUG - org.springframework.transaction.support.TransactionSynchronizationManager  - Retrieved value [org.springframework.orm.hibernate3.SessionHolder@1d381d2] for key [org.hibernate.impl.SessionFactoryImpl@f01771] bound to thread [main]
                    30/06 10:35:35: DEBUG - org.springframework.transaction.support.TransactionSynchronizationManager  - Bound value [org.springframework.jdbc.datasource.ConnectionHolder@b301f2] for key [org.springframework.jdbc.datasource.DriverManagerDataSource@179953c] to thread [main]
                    30/06 10:35:35: DEBUG - org.springframework.transaction.support.TransactionSynchronizationManager  - Initializing transaction synchronization
                    30/06 10:35:35: DEBUG - org.springframework.transaction.support.TransactionSynchronizationManager  - Retrieved value [org.springframework.orm.hibernate3.SessionHolder@1d381d2] for key [org.hibernate.impl.SessionFactoryImpl@f01771] bound to thread [main]
                    30/06 10:35:35: DEBUG - org.springframework.transaction.support.TransactionSynchronizationManager  - Retrieved value [org.springframework.orm.hibernate3.SessionHolder@1d381d2] for key [org.hibernate.impl.SessionFactoryImpl@f01771] bound to thread [main]
                    Hibernate: insert into PROJECT (code, description, duration, name, problematic, program, type, rootPBS, operationalObjective, version, creationDate, impact, scope, manDays, output, MANAGER, SPONSOR) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
                    30/06 10:35:35: DEBUG - org.springframework.transaction.support.TransactionSynchronizationManager  - Retrieved value [org.springframework.orm.hibernate3.SessionHolder@1d381d2] for key [org.hibernate.impl.SessionFactoryImpl@f01771] bound to thread [main]
                    30/06 10:35:35: DEBUG - org.springframework.transaction.support.TransactionSynchronizationManager  - Retrieved value [org.springframework.orm.hibernate3.SessionHolder@1d381d2] for key [org.hibernate.impl.SessionFactoryImpl@f01771] bound to thread [main]
                    30/06 10:35:35: DEBUG - org.springframework.transaction.support.TransactionSynchronizationManager  - Clearing transaction synchronization
                    30/06 10:35:35: DEBUG - org.springframework.transaction.support.TransactionSynchronizationManager  - Removed value [org.springframework.jdbc.datasource.ConnectionHolder@b301f2] for key [[email protected]3c] from thread [main]
                    30/06 10:35:35: DEBUG - org.springframework.transaction.support.TransactionSynchronizationManager  - Removed value [org.springframework.orm.hibernate3.SessionHolder@1d381d2] for key [org.hibernate.impl.SessionFactoryImpl@f01771] from thread [main]
                    I use a MySQL database version:
                    mysql Ver 14.12 Distrib 5.0.37, for Win32 (ia32)

                    tx,
                    Stijn

                    Comment


                    • #11
                      Are you using InnoDB?
                      Last edited by karldmoore; Aug 29th, 2007, 11:28 AM.

                      Comment


                      • #12
                        no I'm not
                        is that required for transactions?

                        Comment


                        • #13
                          I'm not a MySQL expert but I guess that could be the problem.
                          To use transactions as demonstrated in the preceding section, you must be using a transaction-safe table type—either InnoDB or BDB. There are various pieces of syntax that will get the same effect.
                          http://dev.mysql.com/books/mysqlpres...rial/ch10.html
                          Last edited by karldmoore; Aug 29th, 2007, 11:28 AM.

                          Comment


                          • #14
                            tx
                            I'll try this first thing tomorrow and let you know if it worked.

                            greetz

                            Comment


                            • #15
                              Originally posted by TheStijn View Post
                              I'll try this first thing tomorrow and let you know if it worked.
                              There have been quite a few threads that have been fixed by doing the same thing, hopefully this will be the same in your case .
                              Last edited by karldmoore; Aug 29th, 2007, 11:28 AM.

                              Comment

                              Working...
                              X