Why doesn't openSession work but getCurrentSession works in Spring Hibernate

霸气de小男生 提交于 2019-12-20 09:46:01

问题


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.


回答1:


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.



来源:https://stackoverflow.com/questions/21067307/why-doesnt-opensession-work-but-getcurrentsession-works-in-spring-hibernate

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!