1

I'm working with Spring 3 , and I use Hibernate3 as the O/R mapper.While testing my DAO classes I intended to declare my test classes as @Transactional, so that I could rollback the stuff in my DB. DAO classes work fine, however the rollback never happens. this is how my test class looks like:

    @BeforeTransaction
    public void createTestData() {
            // instantiate User objects
    }

    @Before
    public void insertTestData() {
        jdbcTemplate.update("INSERT INTO USER VALUES" + user1);
        jdbcTemplate.update("INSERT INTO USER VALUES" + user2);
        jdbcTemplate.update("INSERT INTO USER VALUES" + user3);
        }

    @Test
    @Rollback(true)
    public void testCheckAvailability() {
        boolean trueResult = userDao.checkAvailability("shaaadi");
        boolean falseResult = userDao.checkAvailability("elthefar");
            assertEquals("Invalid output", true, trueResult);
            assertEquals("Invalid output", false, falseResult);
    }


}

not to forget about the xml file contents:

<?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:p="http://www.springframework.org/schema/p"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">
    <tx:annotation-driven transaction-manager="transactionManager"/>
    <bean 
    class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="location">
            <value>/database.properties</value>
        </property>
    </bean>
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName"><value>${jdbc.driverClassName}</value></property>
        <property name="url"><value>${jdbc.url}</value></property>
        <property name="username"><value>${jdbc.username}</value></property>
        <property name="password"><value>${jdbc.password}</value></property>

    </bean>

    <bean id="sessionFactory" 
        class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"
        p:dataSource-ref="dataSource">
        <property name="annotatedClasses">
        <list>
            <value>ir.cms.domain.user.User</value>
        </list>
        </property>
        <property name="hibernateProperties">
            <value>
            hibernate.format_sql=true
            hibernate.dialect=org.hibernate.dialect.MySQLDialect
            </value>
        </property>
    </bean>

        <bean id="transactionManager" 
          class="org.springframework.orm.hibernate3.HibernateTransactionManager"
          p:sessionFactory-ref="sessionFactory" />



    <bean id="userDao" 
        class="ir.cms.dao.user.impl.UserDaoImpl"
        p:sessionFactory-ref="sessionFactory" />



</beans>

Finally , I should add that DAO classes are not transactional , and are only annotated as @Repository. I appreciate any suggestion :)

ye9ane
  • 1,959
  • 3
  • 18
  • 31
  • 4
    Are you using MyISAM by any chance? It's not transactional by design – Tomasz Nurkiewicz Dec 08 '12 at 19:58
  • 2
    It seems your tests don't update anything in the database. Only the Before method does. I'm not sure the Before method is executed in the same transaction as the test method itself. – JB Nizet Dec 08 '12 at 20:00
  • Are your dao classes using `getCurrentSession` or HibernateTemplate instead? If it's HibernateTemplate please check that it's not configured to open new session every time. – Boris Treukhov Dec 08 '12 at 22:09
  • @JBNizet : Unilike BeforeTransaction,the Before method is executed in the same transaction – ye9ane Dec 09 '12 at 03:08
  • @BorisTreukhov I use HibernateTemplate, but I don't know where I can configure it's session management. I also googled it but it didn't help. is that supposed to be in my xml file? – ye9ane Dec 09 '12 at 05:52
  • please post the source code of user DAO(edit the question) . As for the hibernate template there were two approaches - some people were using it as singleton, some people preferred to create a separate instance per DAO. Now "@transactional" service method + getCurrentSession in DAO is the recommended approach. – Boris Treukhov Dec 09 '12 at 07:41
  • Also Spring Data JPA is gaining popularity - it effectively creates the implementation of repository (domain-driven DAO counterpart) with a bean factory so you only define the interface of repository, consider using it in the new projects. – Boris Treukhov Dec 09 '12 at 07:49
  • I think that `hibernate.current_session_context_class=thread` is not compatible with Spring you should rely on Spring transaction management for opening hibernate sessions and binding them to the current thread. – Boris Treukhov Dec 09 '12 at 08:42
  • See http://stackoverflow.com/questions/4293098/how-to-integrate-spring-with-hibernate-session-and-transaction-management It seems that `hibernate.current_session_context_class=thread` forces Spring not to begin its own transactions. But tbh the interaction between transaction manager, hibernate template, and hibernate itself that is binding transactions to the threads is too complex :-). – Boris Treukhov Dec 09 '12 at 08:51
  • @user1888304 does it work without `hibernate.current_session_context_class=thread` ? – Boris Treukhov Dec 09 '12 at 09:48
  • @BorisTreukhov No,not yet,I almost tried every thing, I decided to do the rollback manually for now and continue my project. The more I work with Spring , the better I can understand Transactions and sessions.Thank you for your knowledge and ideas ;) – ye9ane Dec 09 '12 at 16:15
  • 1
    @BorisTreukhov I finally could realize the problem . My database is MySQL and I had not enabled the innoDB mode. – ye9ane Dec 11 '12 at 15:38
  • 1
    I think you should add this as an answer and mark it as accepted then, so other users will be able to find the solution))) – Boris Treukhov Dec 11 '12 at 15:49

1 Answers1

1

My Problem is finally solved. I was using MySQL, and InnoDB mode was off.

ye9ane
  • 1,959
  • 3
  • 18
  • 31