2017-09-14 89 views
0

它是我第一個非常簡單的Spring-Hibernate應用程序。無法從SessionFactory獲取CurrentSession(),獲取HibernateException

我得到這個
「無法獲得交易同步會話當前線程的」錯誤
當我試圖從SessionFactory的獲取當前會話。

我嘗試下面的東西..

    在吾道使用@Repository,@Transactional
  1. 配置了TransactionManager。
  2. 在我的實體類中使用@實體。

我的根的context.xml

<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:tx="http://www.springframework.org/schema/tx" 
    xmlns:mvc="http://www.springframework.org/schema/mvc" 
    xsi:schemaLocation="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 
       http://www.springframework.org/schema/tx 
       http://www.springframework.org/schema/tx/spring-tx.xsd"> 

        <!--  <context:property-placeholder 
        location="classpath:../properties/db.properties" /> --> 

<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/hib" /> 
    <property name="username" value="root" /> 
    <property name="password" value="" />  
</bean> 

    <bean id="sessionFactory" 
     class="org.springframework.orm.hibernate5.LocalSessionFactoryBean"> 
    <property name="dataSource" ref="dataSource" /> 
    <property name="packagesToScan" value="com.nin.entity" /> 
    <property name="hibernateProperties"> 
     <props> 
     <prop 
     key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop> 
      <prop key="hibernate.show_sql">true</prop> 
      <prop key="hibernate.default_schema">hib</prop> 
     </props> 
    </property> 

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

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



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

我的dispatcherServlet.xml

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

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

    <mvc:annotation-driven/> 

    </beans> 

吾道類

  package com.nin.dao; 

     import org.hibernate.Session; 
     import org.hibernate.SessionFactory; 
     import org.springframework.beans.factory.annotation.Autowired; 
     import org.springframework.stereotype.Repository; 
     import org.springframework.transaction.annotation.Transactional; 

     import com.nin.entity.Student; 



    @Repository 
     public class DaoImpl {  

       @Autowired 
       private SessionFactory sf; 

       @Transactional 
       public void register (Student st){ 

      sf.getCurrentSession(); //Getting Error at this line. 

     //  Session session = sf.getCurrentSession(); 
     //  session.save(st); 

     } 
    } 

最後我的實體類

 package com.nin.entity; 

     import javax.persistence.Column; 
     import javax.persistence.Entity; 
     import javax.persistence.Id; 
     import javax.persistence.Table; 


    @Entity 
    @Table(name="student") 
    public class Student { 


    @Column(name="name") 
    private String name; 

    @Id 
    @Column(name="rollno") 
    private String rollno; 
    @Column(name="password") 
    private String password; 
    @Column(name="city") 
    private String city; 



    public Student(){}; 
    //and getters and setters.. 

在此先感謝和抱歉問題我的英語&表示。

+1

你已經在你的根上下文中定義了你的事務等等(由ContextLoaderListener加載你的組件是由DispatcherServlet掃描的)AOP不會跨越ApplicationContext的 –

+0

OK,我明白了,我呢?我應該在根環境中設置組件掃描嗎? –

+0

嘿,那解決了這個問題,我把所有的東西都搬到了dispatcherServlet.xml。請回答,所以我可以upvote :) –

回答

1

問題是您的Hibernate和事務配置位於由ContextLoaderListener加載的配置文件中。鑑於您的組件由於該文件中的<component-scan />而被DispatcherServlet加載。

使用類似事務的事物時,通過AOP應用這些事務。 AOP通過後處理bean應用。後處理僅適用於相同上下文中的bean,否則您可能會得到奇怪的結果。

由於您沒有2個上下文,因此AOP的內容與您想要應用AOP的實際組件不同。

您可以將所有內容都放在一個上下文中,也可以將<context:component-scan />移動到包含事務配置的配置中。

注:如果你有同樣的<component-scan />在配置文件中所有的組件都需要進行兩次加載和最近的組分(在這種情況下控制器)正在使用你有同樣的問題。

+0

解決it.thanks。 –