2013-11-09 68 views
6

我有一個應用程序與Spring和Hibernate3運行良好的生產。以下是在Spring的applicationContext.xml中配置會話工廠的配置使用current_session_context_class屬性休眠3休眠4

 <bean id="sessionFactory" 
    class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> 
    <property name="dataSource" ref="dataSource" /> 
    <property name="mappingDirectoryLocations"> 
     <list> 
      <value>classpath:/hibernate</value> 
     </list> 
    </property> 
    <property name="hibernateProperties"> 
     <props> 
      <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect 
      </prop> 
      <prop key="hibernate.show_sql">true</prop> 
      <prop key="hibernate.format_sql">true</prop> 
      <prop key="hibernate.use_sql_comments">true</prop> 
      <prop key="hibernate.max_fetch_depth">2</prop> 
      <prop key="hibernate.autocommit">false</prop> 
      <prop key="hibernate.current_session_context_class ">thread</prop> 
          <prop key="hibernate.generate_statistics">true</prop> 
      <prop key="hibernate.jdbc.batch_size">20</prop> 
     </props> 
    </property> 
</bean> 

<bean id="txManager" 
    class="org.springframework.orm.hibernate3.HibernateTransactionManager"> 
    <property name="sessionFactory" ref="sessionFactory" /> 
</bean> 
<!-- the transactional advice (what 'happens'; see the <aop:advisor/> bean 
    below) --> 
<tx:advice id="txAdvice" transaction-manager="txManager"> 
    <!-- the transactional semantics... --> 
    <tx:attributes> 
     <tx:method name="*" propagation="REQUIRED" /> 
     <tx:method name="get*" propagation="SUPPORTS" read-only="true" /> 
     <tx:method name="count*" propagation="SUPPORTS" read-only="true" /> 
     <tx:method name="validate*" propagation="SUPPORTS" 
      read-only="true" /> 
     <tx:method name="find*" propagation="SUPPORTS" read-only="true" /> 
     <tx:method name="login" propagation="SUPPORTS" read-only="true" /> 
    </tx:attributes> 
</tx:advice> 

<!-- ensure that the above transactional advice runs for any execution of 
    an operation defined by the service interfaces --> 
<aop:config> 
    <aop:pointcut id="projectServiceOperation" 
     expression="execution(* com.service.project.IProjectService.*(..))" /> 
    <aop:advisor advice-ref="txAdvice" pointcut-ref="projectServiceOperation" /> 
</aop:config> 

它在生產中工作正常。

現在爲另一個項目我們正在遷移到Hibernate4。我們複製了相同的配置,除了使用Hierrnate 4的SessionFactory,TransacionManager等從 org.springframework.orm.hibernate4。*包。 然而,它開始給出例外說:「保存無效,沒有活動交易」。 搜索了一下後,很多人似乎都面臨的問題和幾個人建議不要使用

 <prop key="hibernate.current_session_context_class ">thread</prop> 

屬性和它的工作。它也爲我工作。從帖子中可以收集到的所有信息都與上下文會話和線程策略干擾Spring的會話管理策略有關。但是,沒有我能找到任何具體答案的地方。 另外,它爲什麼使用Hibernate3而不是Hibernate4。有什麼區別,發生了什麼變化?其他配置都是一樣的。我沒有使用@Transactional,而是使用老派的XML方式。

Can somebody point me to clear explaination for this behavioural difference in Hibernate3 and Hibernate4? 

回答

6

這取決於春天的版本,但在與該媒體同時使用必須避免春季(除非你使用JTA進行交易,那麼你需要配置此)一般瞎搞。

從休眠3.1開始,就有一些稱爲情境會話的東西,因爲休眠提供了CurrentSessionContext接口。有幾種實現方式(threadThreadLocalSessionContext的簡稱)。 Spring有自己的這個接口實現類SpringSessionContext

默認情況下,Spring會將該屬性設置爲CurrentSessionContext的Springs實現,如果將其設置爲其他內容(除JTA外),這將打破彈簧管理hibernate會話(以及事務)的能力。

現在在彈簧的舊版本(我假設你也升級了Spring,以便能夠使用hibernate)和hibernate 3相結合,還有一些關於獲取會話的其他技巧(由於與舊版本的3.x版本向後兼容的冬眠)。這使得斯普林更少依賴於該財產的價值。 (Spring爲SessionFactory創建了一個代理,並基本攔截了getSession方法來管理會話)。

+0

是的,我把Spring從2.5升級到了3.2.4。我想你的答案足以解釋在春季處理會話中的行爲差異。並且它與Spring比Hibernate更相關嗎?(或者兩者兼有?) –

+0

但是您能詳細解釋一下上下文會話以及它們爲什麼被引入。如果你有一些有用的鏈接,而不是hibernate docs,它解釋了hibernate的整個會話處理以及Spring在處理這些事情方面的方法和方法,我將非常感激。當然我可以調試代碼,但是現在我需要在理論上更清楚一些,然後才能深入代碼 –

+0

@ShaileshVaishampayan Spring 2.5和3.2之間的區別可以用最小的hibernate版本來解釋(3.2需要hibernate 3.2,它允許更清潔的整合)。 http://stackoverflow.com/questions/7871386/what-is-contextual-sessions-in-hibernate有關於上下文會話的更多信息。但簡而言之,在上下文會話之前,需要自己跟蹤當前會話(將會話存儲在實例變量中)。現在,它被委派給hibernate,並且使得像hibernate這樣的框架更加容易。 –