svjn
svjn

Reputation: 914

Spring @Transactional not committing records

I use Spring with Hibernate. I am using following configurations. When I try to save through Spring transaction, the record never commits.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p"
    xsi:schemaLocation="
    http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/mvc 
    http://www.springframework.org/schema/mvc/spring-mvc.xsd
    http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context.xsd

    <context:component-scan base-package="com.wpt.controllers,com.wpt.dao" />

    <mvc:annotation-driven />

    <mvc:default-servlet-handler />

    <bean id="viewResolver"
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass"
            value="org.springframework.web.servlet.view.JstlView" />
        <property name="prefix" value="/WEB-INF/views/" />
        <property name="suffix" value=".jsp" />
    </bean>

    <bean id="wptDatasource" class="org.apache.commons.dbcp.BasicDataSource"
        destroy-method="close">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://localhost:3306/wp" />
        <property name="username" value="user" />
        <property name="password" value="pass" />
    </bean>
    <bean id="hibernate4AnnotatedSessionFactory"
            class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
            <property name="dataSource" ref="wptDatasource" />
            <property name="packagesToScan" value="com.wpt.models" />
            <property name="hibernateProperties">
                <props>
                    <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
                    <prop key="hibernate.current_session_context_class">thread</prop>
                    <prop key="hibernate.show_sql">false</prop>
                </props>
            </property>
        </bean>

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

MyControllerClass

@Transactional
@RequestMapping(...)
public String saveRecords(@ModelAttribute("orderObj") Order order){
  for(Item item : order.getItems()){
    itemDAO.save(item);
  }
  return "saveSuccess";
}

MyDAOClass

public void save(Item item){
  session = sf.openSession();
  session.save(item);
  session.close();
}

The above @Transactional configuration not committing the record. But if I remove @Transactional from spring controller and use Hibernate transaction as below, the record commits.

public void save(Item item){
  session = sf.openSession();
  Transaction tx = session.beginTransaction();
  session.persist(item);
  tx.commit();
  session.close();
}

This class commits the record. I've gone through some forums and it's mentioned that @Transactional will take care of committing records. What mistake I am doing here? Can someone help?

Thanks in advance.

Upvotes: 1

Views: 6448

Answers (1)

svjn
svjn

Reputation: 914

It worked after I have added <tx:annotation-driven /> annotation to my configuration xml & removed hibernate.current_session_context_class from hibernateSessionFactory bean. Given the changes below.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context"
    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/mvc 
    http://www.springframework.org/schema/mvc/spring-mvc.xsd
    http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context.xsd
    http://www.springframework.org/schema/tx 
    http://www.springframework.org/schema/tx/spring-tx.xsd">

<context:component-scan base-package="com.wpt.controllers,com.wpt.dao" />

<mvc:annotation-driven />

<mvc:default-servlet-handler />

<bean id="viewResolver"
    class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="viewClass"
        value="org.springframework.web.servlet.view.JstlView" />
    <property name="prefix" value="/WEB-INF/views/" />
    <property name="suffix" value=".jsp" />
</bean>

<bean id="wptDatasource" class="org.apache.commons.dbcp.BasicDataSource"
    destroy-method="close">
    <property name="driverClassName" value="com.mysql.jdbc.Driver" />
    <property name="url" value="jdbc:mysql://localhost:3306/wp" />
    <property name="username" value="user" />
    <property name="password" value="pass" />
</bean>
<bean id="hibernate4AnnotatedSessionFactory"
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="wptDatasource" />
        <property name="packagesToScan" value="com.wpt.models" />
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
                <!-- <prop key="hibernate.current_session_context_class">thread</prop> -->
                <prop key="hibernate.show_sql">false</prop>
            </props>
        </property>
    </bean>

    <tx:annotation-driven transaction-manager="transactionManager"/>
    <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"
        p:sessionFactory-ref="hibernate4AnnotatedSessionFactory">
    </bean>
</beans>

Then I have included org.springframework.transaction.annotation.Transactional annotation to all my service methods & removed all transactions from my DAO classes.

public void save(Item item){
  //session = sf.openSession();
  session.save(item);
  //session.close();
}

Thanks all for your help.

Upvotes: 0

Related Questions