无法使用“getcurrentsession”获取当前线程的事务同步会话,但使用“opensession”工作正常吗?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了无法使用“getcurrentsession”获取当前线程的事务同步会话,但使用“opensession”工作正常吗?相关的知识,希望对你有一定的参考价值。

我是spring mvc和Hibernate的新手我正在尝试使用spring mvc和hibernate创建一个示例登录应用程序,但是在运行以下代码行时:

session=this.sessionFactory.getCurrentSession();

我收到以下错误:

org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread
    at org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:134)
    at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:1014)
    at com.peddle.repository.UserProfileRepositoryImpl.getuserByName(UserProfileRepositoryImpl.java:46)

如果我使用“opensession”代替“get currentsession”,那么这个错误可以被处理。但我想知道我错误的配置细节是什么,因为我无法使用hibernate获取当前会话。

以下是代码和配置文件的详细信息:

1] Spring servlet.xml

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans     
        http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context-3.1.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd">

<!-- bean JSP view resolver here -->    
    <context:component-scan base-package="com.package" />    
    <mvc:annotation-driven />       
<!--  List of Bean classes used -->         
</beans>

2] DB-Config.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans"
        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.xsd">

    <bean
        class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="location">
            <value>classpath:database.properties</value>
        </property>
    </bean>

    <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="${jdbc.driverClassName}" />
        <property name="url" value="${jdbc.url}" />
        <property name="username" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
    </bean>

    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.current_session_context_class ">thread</prop>
                <prop key="hibernate.dialect">org.hibernate.dialect.mysqlDialect</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.hbm2ddl.auto">update</prop>
                <prop key="hibernate.hbm2ddl.import_files_sql_extractor">org.hibernate.tool.hbm2ddl.MultipleLinesSqlCommandExtractor
                </prop>
            </props>
        </property>
<!--  Mapping all @entity classes to table -->
        <property name="packagesToScan" value="com.entity" />
    </bean>

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

    <tx:annotation-driven transaction-manager="transactionManager"/>

    <bean id="transactionInterceptor"
        class="org.springframework.transaction.interceptor.TransactionInterceptor">
        <property name="transactionManager" ref="transactionManager" />
        <property name="transactionAttributeSource">
            <value>
            </value>
        </property>
    </bean>

    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"/>
    </bean>

</beans>

网络

<web-app id="WebApp_ID" version="2.4"
    xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
    http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

    <display-name>Peddle Customer</display-name>

    <servlet>
        <servlet-name>spring</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>spring</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring-servlet.xml,
        /WEB-INF/spring-security.xml, /WEB-INF/DBConfig.xml</param-value>
    </context-param>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <!-- Spring Security -->
    <filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>
                  org.springframework.web.filter.DelegatingFilterProxy
                </filter-class>
    </filter>

    <filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

</web-app>

4]服务层

@Service
class Services
{
      @Transactional
    @Override
    public UserCustomer getuserByName(UserDetails userDetails) {
        // TODO Auto-generated method stub
        return userProfileRepository.getuserByName(userDetails);
    }
}

5]存储库层

@Repository
public class UserProfileRepositoryImpl
{
      @Autowired
    SessionFactory sessionFactory;
   Transaction transaction = null;
    Session session = null;

     @Override
    public UserCustomer getuserByName(UserDetails userDetails){
        UserCustomer Usercustomer=null;
        try {
            session=this.sessionFactory.getCurrentSession();
            transaction = session.beginTransaction();
             // related implementation here
        } catch (HibernateException e) {
            e.printStackTrace();
        }

        return Usercustomer;
    }
}
答案

OpenSession始终打开新品牌会话,而当前会话则不会。

的openSession:

当您调用SessionFactory.openSession时,它总是重新创建新的Session对象并将其提供给您。您需要显式刷新和关闭这些会话对象。由于会话对象不是线程安全的,因此您需要在多线程环境中为每个请求创建一个会话对象,并在Web应用程序中为每个请求创建一个会话。

CurrentSession:

当你调用SessionFactory时。 getCurrentSession,它将为您提供在hibernate上下文中并由内部hibernate管理的会话对象。它与事务范围有关。当你调用SessionFactory时。 getCurrentSession,如果不存在则创建一个新的Session,否则使用当前hibernate上下文中的相同会话。它在事务结束时自动刷新和关闭会话,因此您不需要在外部执行。如果在单线程环境中使用hibernate,则可以使用getCurrentSession,因为与每次创建新会话相比,它的性能更快。

以上是关于无法使用“getcurrentsession”获取当前线程的事务同步会话,但使用“opensession”工作正常吗?的主要内容,如果未能解决你的问题,请参考以下文章

JTASessionContext 与 JDBCTransactionFactory 一起使用;使用 getCurrentSession() 无法正确操作自动刷新

sessionfactory.getcurrentsession()获取不到session

hibernate的 openSession 和 getCurrentSession

Hibernate getCurrentSession()和openSession()的区别

Hibernate中getCurrentSession()与openSession()的区别及应用

getCurrentSession 与 openSession区别