4

I have written a sample Spring Hibernate application o understand how Spring hibernate integration works.

Here is my applicationContext.xml

<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:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:task="http://www.springframework.org/schema/task"
    xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.2.xsd">

    <context:component-scan base-package="com.general" />

    <tx:annotation-driven />

    <bean id="dataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
        <property name="url" value="jdbc:oracle:thin:@localhost:1521:orcl" />
        <property name="username" value="system" />
        <property name="password" value="admin_123" />
    </bean>

    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean ">
        <property name="dataSource" ref="dataSource"></property>
        <property name="packagesToScan" value="com.general"></property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
                <prop key="hibernate.show_sql">true</prop>
            </props>
        </property>
    </bean>

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

Then, my service class is like that

package com.general;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;


@Service("employeeService")
public class EmployeeServiceImpl implements EmployeeService{

    @Autowired
    private SessionFactory sessionFactory;

    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    @Transactional
    public void saveEmployee(Employee emp) {
        Session session = sessionFactory.getCurrentSession();//.openSession();
        session.save(emp);
    }

}

And my main class is

public class App {

    public static void main(String[] args) {
        System.out.println("load context");
        ConfigurableApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        Employee em = new Employee();
        em.setId(1l);
        em.setName("John");

        EmployeeService emService = (EmployeeService) context.getBean("employeeService");
        emService.saveEmployee(em);
    }

}

If I run this application using getCurrentSession method, then it runs fine and employee is saved into the database but if i use openSession method, then no SQL query is fired and thus nothing is saved into the database.

I am not sure why this is happening. May be I don't have correct understanding of getCurrentSession () and openSession (). Can please someone let me know the reason behind it.

Anand
  • 20,708
  • 48
  • 131
  • 198
  • possible duplicate of [Hibernate openSession() vs getCurrentSession()](http://stackoverflow.com/questions/8046662/hibernate-opensession-vs-getcurrentsession) – MariuszS Jan 11 '14 at 20:16

1 Answers1

12

The fact that you have @Transactional on a method in a @Service annotated class along with a TransactionManager means the whole transaction lifecycle will be managed by Spring.

When your saveEmployee method is called, Spring will open a Session, start a transaction, execute your code, commit the transaction and close the Session. The Session it starts is bound to the current thread and available through getCurrentSession().

If you instead use openSession(), you are opening a completely unrelated Session, not managed by Spring's TransactionManager. As such, the transaction won't be committed and the Sessionwon't be closed unless you do it yourself.

Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
  • 1
    if the session is closed at the end of a transaction, how can the same session (already closed) be reopened by another call of getCurrentSession() in the same thread? – user2953113 Sep 27 '15 at 02:45
  • 1
    @user2953113 It doesn't. A new one is created and returned. – Sotirios Delimanolis Sep 28 '15 at 04:11
  • thanks. If `saveEmployee` method is called twice from the same thread one after the other, there will be 2 different transactions, right? one for each call. – user2953113 Sep 28 '15 at 17:00
  • 1
    @user2953113 I believe there will be two transactions, yes. But there might only be one `Session`. – Sotirios Delimanolis Sep 28 '15 at 22:24
  • @SotiriosDelimanolis- How can there by only one session. Each transaction opens a new session..isn't it? – Anand Apr 28 '16 at 13:28
  • @Anand I don't know about all implementations. But a `SessionFactory` may be pooling the `Session` objects per thread. It's been a long time and I haven't worked with Hibernate so I can't give you a positive answer. – Sotirios Delimanolis Apr 28 '16 at 14:24