使用current_session_context_class属性hibernate 3 hibernate 4 [英] using current_session_context_class property hibernate 3 hibernate 4

查看:142
本文介绍了使用current_session_context_class属性hibernate 3 hibernate 4的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Spring和Hibernate3在生产环境中运行良好的应用程序。以下是Spring的applicationContext.xml中会话工厂的配置:

 < bean id =sessionFactory
class = org.springframework.orm.hibernate3.LocalSessionFactoryBean >
< property name =dataSourceref =dataSource/>
< property name =mappingDirectoryLocations>
< list>
< value> classpath:/ hibernate< / value>
< / list>
< / property>
< property name =hibernateProperties>
<道具>
< 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>
< /道具>
< / property>
< / bean>

< bean id =txManager
class =org.springframework.orm.hibernate3.HibernateTransactionManager>
< property name =sessionFactoryref =sessionFactory/>
< / bean>
<! - 交易建议(发生了什么;请参阅下面的< aop:顾问/> bean
) - >
< tx:advice id =txAdvicetransaction-manager =txManager>
<! - 事务性语义... - >
< tx:attributes>
< tx:method name =*propagation =REQUIRED/>
< tx:方法名称=get *propagation =SUPPORTS只读=true/>
< tx:方法名称=count *propagation =SUPPORTS只读=true/>
< tx:method name =validate *propagation =SUPPORTS
read-only =true/>
< tx:method name =find *propagation =SUPPORTSread-only =true/>
< tx:方法名称=登录传播=SUPPORTS只读=true/>
< / tx:属性>
< / tx:advice>

<! - 确保上述事务通知针对由服务接口定义的操作的任何
执行运行 - >
< aop:config>
< aop:pointcut id =projectServiceOperation
expression =execution(* com.service.project.IProjectService。*(..))/>
< / aop:config>

它在制作中正常运行。

现在为另一个项目,我们正在迁移到Hibernate4。我们复制了相同的配置,除了从
org.springframework.orm.hibernate4。*包使用Hierrnate 4的SessionFactory,TransacionManager等。
然而,它开始给出例外说:没有活动交易保存无效。
搜索了一下之后,很多人似乎都遇到了问题,有几个人建议不要使用

 < prop key =hibernate.current_session_context_class>线程< / prop> 

属性和它的工作。它也为我工作。从帖子中可以收集到的所有信息都与上下文会话和线程策略干扰Spring的会话管理策略有关。但是,没有我能找到任何具体答案的地方。
另外,为什么它使用Hibernate3而不是Hibernate4。有什么区别,发生了什么变化?其他配置都是一样的。

 有人可以指出我清楚解释Hibernate3中的这种行为差异和Hibernate4? 


解决方案

它取决于spring的版本,在使用Spring时必须避免使用该属性(除非使用JTA进行事务处理,则需要对其进行配置)。

从Hibernate 3.1开始,有一些称为上下文会话的东西,因为hibernate提供了 CurrentSessionContext 接口。有几种实现方式( thread ThreadLocalSessionContext 的缩写)。 Spring有它自己实现的接口 SpringSessionContext 类。



Spring默认将属性设置为Springs实现 CurrentSessionContext ,当它被设置为别的东西(除JTA之外)时,这将破坏管理hibernate会话(以及事务)的能力。

现在在Spring的旧版本中(我假设你也升级了Spring,以便能够使用hibernate)和hibernate 3相结合,还有一些关于获取会话的欺骗(由于与旧版3.x版本的向后兼容)。这使得斯普林更少依赖于该财产的价值。 (Spring为 SessionFactory 创建了一个代理,并基本拦截了 getSession 方法来管理会话)。


I have an application with Spring and Hibernate3 running well in production. Following is the config for session factory in Spring's applicationContext.xml

       <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>

It is working fine in production.

Now for another project we are migrating to Hibernate4. we copied over the same configuration except using Hierrnate 4's SessionFactory,TransacionManager etc. from org.springframework.orm.hibernate4.* package. However it started giving exception saying "Save is not valid without active transaction". After searching a bit many people seemed to have faced the problems and several people suggested not to use

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

property and it worked. It also worked for me. All little information I could gather from the posts that it has something to do with contextual sessions and thread strategy interfering with Spring's session management strategy. But no where I could find any concrete answer. Also, why did it work with Hibernate3 and not with Hibernate4. What is the difference and what has changed? Every other configuration is same. I am not using @Transactional but the old school XML way.

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

解决方案

It depends on the version of spring but in general messing around with that property whilst using Spring must be avoided (unless you use JTA for transactions then you need to configure this).

As of Hibernate 3.1 there is something called contextual sessions and for that hibernate provides the CurrentSessionContext interface. There are several implementations for this (and thread is short for ThreadLocalSessionContext). Spring has its own implementation of this interface the SpringSessionContext class.

Spring by default sets the property to Springs implementation of the CurrentSessionContext, when this is set to something else (other then JTA) this will break springs ability to manage the hibernate session (and thus the transaction).

Now in older versions of spring (and I assume you also upgraded Spring to be able to use hibernate) combined with hibernate 3 there was some other trickery involved regarding getting the session (due to backwards compatibility with older 3.x versions of hibernate). This made Spring less depended on the value of that property. (Spring created a proxy for the SessionFactory and basically intercepted the getSession method to be able to manage the session).

这篇关于使用current_session_context_class属性hibernate 3 hibernate 4的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆