1

I am trying to use @Transactional annotation using Spring 4.0.5, and hibernate, using mysql db.

===== The below is the code =====

The model class is:

package com.vipin.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
    @Entity
    @Table(name="USER_INFO")
    public class UserInfo {
    @Id
    @Column(name="ssnID")
    private int ssnID;
    private String firstName;
    private String lastName;

    public int getSsnID() {
        return ssnID;
    }
    public void setSsnID(int ssnID) {
        this.ssnID = ssnID;
    }
    public String getFirstName() {
        return firstName;
    }
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }
    public String getLastName() {
        return lastName;
    }
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
}

The dao interface which declares the DB operations.

DBOperationsDao.java

package com.vipin.dao;
import com.vipin.model.UserInfo;
public interface DBOperationsDao {
public UserInfo getUserInfo(int ssnId);
public void updateUserInfo(int ssnId);
public void deleteUser(int ssnId);
public void addUser(UserInfo userInfo);
}

Dao interface implementation (simple one)

DBOperationsDaoImpl.java

package com.vipin.dao;
import com.vipin.model.UserInfo;
import org.hibernate.SessionFactory;
import javax.annotation.Resource;
import org.hibernate.Session;
import org.springframework.transaction.annotation.Transactional;

public class DBOperationsDaoImpl implements DBOperationsDao {
private SessionFactory sessionFactory;
public SessionFactory getSessionFactory() {
    return sessionFactory;
}

@Resource(name="sessionFactory")
public void setSessionFactory(SessionFactory sessionFactory) {
    this.sessionFactory = sessionFactory;
    System.out.println("Inside setSessionFactory() method, value of this.sessionFactory is " + this.sessionFactory);
}

@Override
public UserInfo getUserInfo(int ssnId) {
    // TODO Auto-generated method stub
    return null;
}

@Override
public void updateUserInfo(int ssnId) {
    // TODO Auto-generated method stub

}

@Override
public void deleteUser(int ssnId) {
    // TODO Auto-generated method stub

}

@Override
@Transactional
public void addUser(UserInfo userInfo) {
    Session session = this.sessionFactory.openSession();

    System.out.println("Inside addUser() method.. value of session is " + session);
    //session.persist(userInfo);
    session.save(userInfo); 
}
}

I am trying to achieve to use @Transactional annotation to do the transaction management, using Spring 4.0.6 and Hibernate.

The below is the Spring.xml

<?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:jdbc="http://www.springframework.org/schema/jdbc"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:jpa="http://www.springframework.org/schema/data/jpa"
    xmlns:p="http://www.springframework.org/schema/p"
    xsi:schemaLocation="
        http://www.springframework.org/schema/jdbc
        http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config/>
<tx:annotation-driven  proxy-target-class="true" transaction- manager="transactionManager"/> 
<context:component-scan base-package="com.vipin.model"/>
<context:component-scan base-package="com.vipin.dao"/>
<!-- Here we are using apache commons dbcp2 implementation of DataSource -->
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
  <property name="driverClassName" value="com.mysql.jdbc.Driver" />
  <property name="url" value="jdbc:mysql://localhost:3306/SPRINGDB" />
  <property name="username" value="mysql"/>
  <property name="password" value="mysql"/>
</bean>

<bean id="dao" class="com.vipin.dao.DBOperationsDaoImpl"/>

<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
      <property name="dataSource" ref="dataSource"/>
      <property name="packagesToScan" value="com.vipin.model"/>
      <property name="hibernateProperties">
          <props>
              <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
              <prop key="hibernate.show_sql">true</prop>
              <prop key="hibernate.hbm2ddl.auto">update</prop>
          </props>
      </property>   
</bean>

<bean id="transactionManager"   class="org.springframework.orm.hibernate4.HibernateTransactionManager">
  <property name="sessionFactory">
    <ref bean="sessionFactory"/>
  </property>
</bean>

<context:annotation-config/>
</beans>

The main app is:

MainApp.java

package com.vipin.app;

import com.vipin.dao.DBOperationsDao;
import com.vipin.dao.DBOperationsDaoImpl;
import com.vipin.model.UserInfo;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainApp {
    public static void main(String[] args) {

    UserInfo userAdd = new UserInfo();

    userAdd.setSsnID(1);;
    userAdd.setFirstName("Vipin");
    userAdd.setLastName("koul");

    System.out.println("Inside main...");
    ApplicationContext context = new ClassPathXmlApplicationContext("classpath*:/META-INF/spring.xml");
    DBOperationsDao dao = context.getBean("dao", DBOperationsDaoImpl.class);
    dao.addUser(userAdd);
}

}

When i run this program, no rows gets added to DB, and no error/exceptions.

I looked at various post both on google and this site, however didn't get any clues. Any help would be great

CuriousMind
  • 8,301
  • 22
  • 65
  • 134
  • where's the main method starting up the application context? – dimitrisli Oct 27 '14 at 20:57
  • In your spring config file there is `transaction- manager="transactionManager"` (notice the space between transaction and manager). Perhaps that is the cause of your problems? – Bohuslav Burghardt Oct 27 '14 at 20:59
  • Since I don't see the main method, the first think that comes to my mind is: are you using a valid useinfo object? (since you mapped only the ssnId column, you just need to set this property before calling the dao). – Pirulino Oct 27 '14 at 21:01
  • It is copy-paste error, in my project it is correct. – CuriousMind Oct 27 '14 at 21:02
  • Ah, a note: use the getcurrentsession instead of opensession (more details here http://www.javabeat.net/opensession-getcurrentsession-difference-hibernate/). – Pirulino Oct 27 '14 at 21:04
  • 1
    Yes the problem is apparently in the usage of openSession method. It is also explained pretty well in this SO post: http://stackoverflow.com/questions/21067307/why-doesnt-opensession-work-but-getcurrentsession-works-in-spring-hibernate – Bohuslav Burghardt Oct 27 '14 at 21:05
  • I am using it in standalone program. – CuriousMind Oct 27 '14 at 21:06
  • Thanks for your comments, yes after switching from openSession() to getCurrentSession() it is updating the tables. I have to read the different between them. When i explicitly controlled the transaction programatically, i used the openSession(), and i thought the same would work even if we use @Transactional annotation, seems that is not the case, need to understand that. – CuriousMind Oct 27 '14 at 21:15

0 Answers0