current_session_context_class

本文探讨了Spring与Hibernate框架整合时的常见问题,特别是在事务管理方面。指出当使用Spring的AOP进行事务管理时,需要正确配置hibernate.current_session_context_class以确保Spring能够管理Hibernate的事务。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

平时在单独使用hibernate的时候,习惯于配置属性

<property name="current_session_context_class">thread</property>
根据文档,这个是hibernate3.1以后的一个新扩展,目的在于可以让我们在某一个上下文环境(比如说当前线程)中可以通过SessionFactory.getCurrentSession()得到同一个session会话.

后来当我们把spring,hibernate整合的时候,在spring的主配置文件当中,我们也习惯于带入这样的配置
<property name="hibernateProperties">
<props>
<prop key="hibernate.current_session_context_class">thread</prop>
,接下来在spring配置文件中,会使用spring2.x的声明式的方式来配置事务
<tx:advice id="txAdvice" transaction-manager="transactionManager">,<aop:pointcut,<aop:advisor等等配置指定哪些方法上由spring来管理hiberante的事务,这个时候我们试着运行一个类似于这样的方法
public void find() {
Session se = sf.getCurrentSession();
//此处不需要se.beginTransaction(),事务已经交由spring管理
Dept d = (Dept) se.get(Dept.class, new Long(12));
}
会得到一个异常: get is not valid without active transaction.
这个错误一般情况是因为由getCurrentSession得到的session中没有获得的transaction,我们一般要手动的调用se.beginTransaction(),来打开一个活动的事务.但是问题是,我们在spring的配置文件中不是已经通过aop,指定了此处由spring来管理事务吗,怎么还要手动处理事务?

答案: 
<prop key="hibernate.current_session_context_class">thread</prop>改为
<prop key="hibernate.current_session_context_class">org.springframework.orm.hibernate3.SpringSessionContext</prop>(默认配置)

参考:
1. hibernate文档:
2.在hibernate中,thread,jta,manager的配置其实都是对应了3个hibernate的实现类
3.在sessionFactory配置文件中
应将hibernate.current_session_context_class设为org.springframework.orm.hibernate3.SpringSessionContext(默认为此值)应当把session要绑定的上下文设置为由spring环境管理(因为我们的事务aop也是在spring范围中),这个时候spring中的事务配置才会起作用(当然,以前是thread上下文环境的session,而事务托管在spring上下文中,当然spring无法管理到thread上下文的session的事务咯)

综上所述,其实仔细看ThreadLocalSessionContext,JTASessionContext,ManagedSessionContext,SpringSessionContext我们都会发现,他们都实现了一个接口org.hibernate.context.CurrentSessionContext关于这个接口,请参阅 org.hibernate.context.CurrentSessionContext 接口的 Javadoc,那里有关于它的契约的详细讨论。它定义了单一的方法,currentSession(),特定的实现用它来负责跟踪当前的上下文相关的会话
最后,我们知道,其实线程绑定也好,上下文绑定也好,最后都是,使用实现了CurrentSessionContext接口的一个类,来跟踪session,然后我们通过这个类的对象来获得被它跟踪的session,以达到在我们定义的上下文环境中调用getCurrentSession方法获得的总是同一个session
<session-factory> <property name="connection.provider">NHibernate.Connection.DriverConnectionProvider, NHibernate</property> <!-- 每种drever_class对Oracle的性能不一样,OracleClientDriver对高并发性能支持很好;如果需要使用存储过程则必须要使用OracleManagedDataClientDriver; --> <!--<property name="connection.driver_class">NHibernate.Driver.OracleClientDriver</property>--> <!--<property name="connection.driver_class">NHibernate.Driver.OracleDataClientDriver</property>--> <property name="connection.driver_class">NHibernate.Driver.OracleManagedDataClientDriver</property> <property name="connection.connection_string"> <!-- User ID=fheap; Password=fheap; Data Source=(DESCRIPTION=(TRANSPORT_CONNECT_TIMEOUT = 60)(ADDRESS=(PROTOCOL=TCP)(HOST=10.255.1.13)(PORT=1521))(ADDRESS=(PROTOCOL=TCP)(HOST=10.255.1.14)(PORT=1521))(LOAD_BALANCE=yes)(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=cim)(FAILOVER_MODE=(TYPE=SELECT)(METHOD=BASIC)(RETRIES=180)(DELAY=5)))); Pooling=True;Max Pool Size = 100;Min Pool Size = 0;Connect Timeout=500;--> User ID=FHEAP; Password=fheap; Data Source=(DESCRIPTION=(TRANSPORT_CONNECT_TIMEOUT = 60)(ADDRESS=(PROTOCOL=TCP)(HOST=172.17.6.28)(PORT=1521))(LOAD_BALANCE=yes)(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=mesdbtest)(FAILOVER_MODE=(TYPE=SELECT)(METHOD=BASIC)(RETRIES=180)(DELAY=5)))); Pooling=True;Max Pool Size = 100;Min Pool Size = 0;Connect Timeout=500; <!--User ID=fheap; Password=123456; Data Source=(DESCRIPTION=(TRANSPORT_CONNECT_TIMEOUT = 60)(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.85.128)(PORT=1521)))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=XE)));Pooling=True;Max Pool Size = 150;Min Pool Size = 10;Connect Timeout=500;--> <!--User ID=mesforehope; Password=mesforehope; Data Source=(DESCRIPTION=(TRANSPORT_CONNECT_TIMEOUT = 60)(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=10.255.1.34)(PORT=1521)))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=mesdb)));--> </property> <property name="show_sql">false</property> <property name="dialect">NHibernate.Dialect.Oracle12cDialect</property> <property name="query.substitutions">true 1, false 0, yes 'Y', no 'N'</property> <!-- If your database setup use an ASCII charset, switch following property to true. --> <property name="oracle.use_n_prefixed_types_for_unicode">false</property> <!-- Depending on your database setup, the default cast length of 4000 may be too big. By example, if previous setting is true, NHibernate may try to use nvarchar2(4000), which will be rejected if its underlying charset is UTF16 and the database MAX_STRING_SIZE is not extended. In such case, reduce it to 2000. --> <property name="query.default_cast_length"></property> <property name="hbm2ddl.keywords">none</property> <!-- 每个线程获取到的session是不一样的。多线程并发一定要配置,否则会导致线程重用,获取一样的session,就会导致后来获取到的session失效 --> <property name="current_session_context_class">thread_static</property> <!--加载映射--> <mapping assembly="Nebula.EAP.Core.Scenario" /> </session-factory> 只更换驱动NHibernate.Driver.OracleClientDriver对其他配置有没有影响
最新发布
06-06
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值