2013-11-09 66 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这样的框架更加容易。 –