`
啸笑天
  • 浏览: 3430796 次
  • 性别: Icon_minigender_1
  • 来自: China
社区版块
存档分类
最新评论

hibernate.current_session_context_class

阅读更多

遇到过的问题:

情景1:

在使用SessionFactory的getCurrentSession方法时遇到如下错误,经过检查,原因如下:

是因为在hibernate.cfg.xml文件中忘记进行了如下设置:

hibernate.current_session_context_class如果是在web容器中运行hibernate,则在hibernate.cfg.xml中加入这句话:

<property name="hibernate.current_session_context_class">jta</property>

如果是在一个单独的需要进行JDBC连接的java application中运行hibernate,则这样设置:

<property name="hibernate.current_session_context_class">thread</property>

 

情景2:

在ssh2中的sessionFactory配置文件中

应将hibernate.current_session_context_class设为org.springframework.orm.hibernate3.SpringSessionContext(默认为此值)

并应用spring管理事务。如果为<prop key="hibernate.current_session_context_class">thread</prop> 则会报异常,

 

所以还是spring中hibernate.current_session_context_class的问题

在spring的类LocalSessionFactoryBean源码,方法buildSessionFactory中将hibernate.current_session_context_class设为org.springframework.orm.hibernate3.SpringSessionContext

if (isExposeTransactionAwareSessionFactory()) {  
   // Set Hibernate 3.1+ CurrentSessionContext implementation,  
   // providing the Spring-managed Session as current Session.  
   // Can be overridden by a custom value for the corresponding Hibernate property.  
   config.setProperty(Environment.CURRENT_SESSION_CONTEXT_CLASS, SpringSessionContext.class.getName());  
   }  

if (this.jtaTransactionManager != null) {  
   // Set Spring-provided JTA TransactionManager as Hibernate property.  
   config.setProperty(Environment.TRANSACTION_STRATEGY, JTATransactionFactory.class.getName());  
   config.setProperty(  Environment.TRANSACTION_MANAGER_STRATEGY, LocalTransactionManagerLookup.class.getName());  
}  else {  
   // Makes the Hibernate Session aware of the presence of a Spring-managed transaction.  
   // Also sets connection release mode to ON_CLOSE by default.  
   config.setProperty(Environment.TRANSACTION_STRATEGY, SpringTransactionFactory.class.getName());  
            }  
 

 

知识总结:

hibernate.current_session_context_class属性

sessionFactory.getCurrentSession()可以完成一系列的工作,当调用时hibernate将session绑定到当前线程,事务结束后hibernate将session从当前线程中释放并且关闭session。当再次调用getCurrentSession()时将得到一个新的session,并重新开始这一系列工作。

这样调用方法如下:

Session session = HibernateUtil.getSessionFactory().getCurrentSession();

session.beginTransaction();

Event theEvent = new Event();

theEvent.setTitle(title);

theEvent.setDate(theDate);

session.save(theEvent);

session.getTransaction().commit();   //不需要close session了。 前提是改值设置为了thread.

 

在一个应用程序中,如果DAO 层使用Spring 的hibernate 模板,通过Spring 来控制session 的生命周期,则首选getCurrentSession ()。

使用Hibernate的大多数应用程序需要某种形式的“上下文相关的” session,特定的session在整个特定的上下文范围内始终有效。然而,对不同类型的应用程序而言,要为什么是组成这种“上下文”下一个定义通常 是困难的;不同的上下文对“当前”这个概念定义了不同的范围。在3.0版本之前,使用Hibernate的程序要么采用自行编写的基于 ThreadLocal的上下文session,要么采用HibernateUtil这样的辅助类,要么采用第三方框架(比如Spring或Pico), 它们提供了基于代理(proxy)或者基于拦截器(interception)的上下文相关session。 

 

从3.0.1版本开 始,Hibernate增加了SessionFactory.getCurrentSession()方法。一开始,它假定了采用JTA事务,JTA事务 定义了当前session的范围和上下文(scope and context)。Hibernate开发团队坚信,因为有好几个独立的JTA TransactionManager实现稳定可用,不论是否被部署到一个J2EE容器中,大多数(假若不是所有的)应用程序都应该采用JTA事务管理。 基于这一点,采用JTA的上下文相关session可以满足你一切需要。 

更好的是,从3.1开始,SessionFactory.getCurrentSession()的后台实现是可拔插的。因此,我们引入了新的扩展接口(org.hibernate.context.CurrentSessionContext)和新的配置参数(hibernate.current_session_context_class),以便对什么是“当前session”的范围和上下文(scope and context)的定义进行拔插。

请参阅org.hibernate.context.CurrentSessionContext接口的Javadoc,那里有关于它的契约的详细讨论。它定义了单一的方法,currentSession(),特定的实现用它来负责跟踪当前的上下文session。Hibernate内置了此接口的三种实现。

org.hibernate.context.JTASessionContext - 当前session根据JTA来跟踪和界定。这和以前的仅支持JTA的方法是完全一样的。详情请参阅Javadoc。

org.hibernate.context.ThreadLocalSessionContext - 当前session通过当前执行的线程来跟踪和界定。详情也请参阅Javadoc。

org.hibernate.context.ManagedSessionContext - 当前session通过当前执行的线程来跟踪和界定。但是,你需要负责使用这个类的静态方法将Session实例绑定、或者取消绑定,它并不会打开(open)、flush或者关闭(close)任何Session。

前两种实现都提供了“每数据库事务对应一个session”的编程模型,也称作每次请求一个session。Hibernate session的起始和终结由数据库事务的生存来控制。假若你在纯粹的 Java SE之上采用自行编写代码来管理事务,而不使用JTA,建议你使用Hibernate Transaction API来把底层事务实现从你的代码中隐藏掉。如果你使用JTA,请使用JTA借口来管理Transaction。如果你在支持CMT的EJB容器中执行代码,事务边界是声明式定义的,你不需要在代码中进行任何事务或session管理操作。

hibernate.current_session_context_class配置参数定义了应该采用哪个org.hibernate.context.CurrentSessionContext实现。注意,为了向下兼容,如果未配置此参数,但是存在org.hibernate.transaction.TransactionManagerLookup的配置,Hibernate会采用org.hibernate.context.JTASessionContext。一般而言,此参数的值指明了要使用的实现类的全名,但那三种内置的实现可以使用简写,即"jta"、"thread"和"managed"。

 

1、getCurrentSession()与openSession()的区别?

在 SessionFactory 启动的时候, Hibernate 会根据配置创建相应的 CurrentSessionContext ,在 getCurrentSession() 被调用的时候,实际被执行的方法是CurrentSessionContext.currentSession() 。在 currentSession() 执行时,如果当前 Session 为空,currentSession 会调用SessionFactory的openSession 。所以getCurrentSession() 对于 Java EE 来说是更好的获取 Session 的方法。

* 采用getCurrentSession()创建的session会绑定到当前线程中,而采用openSession()创建的session则不会

* 采用getCurrentSession()创建的session在commit或rollback时会自动关闭,而采用openSession()创建的session必须手动关闭

2、使用getCurrentSession()需要在hibernate.cfg.xml文件中加入如下配置:

* 如果使用的是本地事务(jdbc事务)

<property name="hibernate.current_session_context_class">thread</property>

* 如果使用的是全局事务(jta事务)

<property name="hibernate.current_session_context_class">jta</property>

* 如果使用的是session的管理机制(不太常用)

<property name="hibernate.current_session_context_class">managed</property>

 

利于ThreadLocal模式管理Session

   早在Java1.2推出之时,Java平台中就引入了一个新的支持:java.lang.ThreadLocal,给我们在编写多线程程序

   时提供了一种新的选择。ThreadLocal是什么呢?其实ThreadLocal并非是一个线程的本地实现版本,它并不是一个Thread,

   而是thread local variable(线程局部变量)。也许把它命名为ThreadLocalVar更加合适。线程局部变量(ThreadLocal)

   其实的功用非常简单,就是为每一个使用某变量的线程都提供一个该变量值的副本,是每一个线程都可以独立地改变自己的副本,

   而不会和其它线程的副本冲突。从线程的角度看,就好像每一个线程都完全拥有一个该变量。 

   ThreadLocal是如何做到为每一个线程维护变量的副本的呢?其实实现的思路很简单,在ThreadLocal类中有一个Map,

   用于存储每一个线程的变量的副本。比如下面的示例实现(为了简单,没有考虑集合的泛型): 

public class HibernateUtil {

public static final ThreadLocal session =new ThreadLocal();

public static final SessionFactory sessionFactory;

   static {

      try {

        sessionFactory = new Configuration().configure().buildSessionFactory();

      } catch (Throwable ex) {

           throw new ExceptionInInitializerError(ex);

      }     

}

     public static Session currentSession () throws HibernateException {

        Session s = session.get ();

        if(s == null) {

          s = sessionFactory.openSession ();

          session.set(s);

           }

         return s;

       }

    public static void closeSession() throws HibernateException {

           Session s = session.get ();

        if(s != null) {

            s.close();

        }

        session.set(null);

    }

}

 

 

 

 

 

分享到:
评论

相关推荐

    Hibernate_3.2.0_符合Java习惯的关系数据库持久化

    3.8.3. 在JTA环境下使用Current Session context (当前session上下文)管理 3.8.4. JMX部署 4. 持久化类(Persistent Classes) 4.1. 一个简单的POJO例子 4.1.1. 实现一个默认的(即无参数的)构造方法...

    维生药业小项目 SSH简单学习项目

    &lt;prop key="current_session_context_class"&gt;thread &lt;prop key="hibernate.show_sql"&gt;true &lt;prop key="hibernate.format_sql"&gt;true &lt;prop key="hibernate.hbm2ddl.auto"&gt;update ...

    hibernate_reference中文文档.pdf

    3.8.3. 在 JTA 环境下使用 Current Session context(当前 session 上下文) 管理 .................................................................. 48 3.8.4. JMX 部署 ........................................

    Hibernate 中文 html 帮助文档

    3.8.3. 在JTA环境下使用Current Session context (当前session上下文)管理 3.8.4. JMX部署 4. 持久化类(Persistent Classes) 4.1. 一个简单的POJO例子 4.1.1. 实现一个默认的(即无参数的)构造方法(constructor)...

    HibernateAPI中文版.chm

    3.8.3. 在JTA环境下使用Current Session context (当前session上下文)管理 3.8.4. JMX部署 4. 持久化类(Persistent Classes) 4.1. 一个简单的POJO例子 4.1.1. 实现一个默认的(即无参数的)构造方法...

    Hibernate中文详细学习文档

    3.8.3. 在JTA环境下使用Current Session context (当前session上下文)管理 3.8.4. JMX部署 4. 持久化类(Persistent Classes) 4.1. 一个简单的POJO例子 4.1.1. 实现一个默认的(即无参数的)构造方法...

    hibernate3.6 文档(pdf 格式)

    1.1. Part 1 - The first Hibernate Application ................................................................ 1 1.1.1. Setup .............................................................................

    Hibernate Reference Documentation3.1

    3.8.3. Current Session context management with JTA 3.8.4. JMX deployment 4. Persistent Classes 4.1. A simple POJO example 4.1.1. Implement a no-argument constructor 4.1.2. Provide an identifier ...

    Hibernate+中文文档

    3.8.3. 在JTA环境下使用Current Session context (当前session上下文)管理 3.8.4. JMX部署 4. 持久化类(Persistent Classes) 4.1. 一个简单的POJO例子 4.1.1. 实现一个默认的(即无参数的)构造方法...

    hibernate3.2中文文档(chm格式)

    3.8.3. 在JTA环境下使用Current Session context (当前session上下文)管理 3.8.4. JMX部署 4. 持久化类(Persistent Classes) 4.1. 一个简单的POJO例子 4.1.1. 实现一个默认的(即无参数的)构造方法...

    SSH第7章上机.zip ACCP8.0

    &lt;entry key="current_session_context_class" value="thread" /&gt; 加入事务管理切面类的配置 &lt;!-- 创建事务管理器(spring针对hibernate实现的事务管理的切面类) --&gt; &lt;bean id="transactionManager" class=...

    hibernate 体系结构与配置 参考文档(html)

    在JTA环境下使用Current Session context (当前session上下文)管理 3.8.4. JMX部署 4. 持久化类(Persistent Classes) 4.1. 一个简单的POJO例子 4.1.1. 实现一个默认的(即无参数的)构造方法(constructor) ...

    Hibernate参考文档

    3.8.3. 在JTA环境下使用Current Session context (当前session上下文)管理 3.8.4. JMX部署 4. 持久化类(Persistent Classes) 4.1. 一个简单的POJO例子 4.1.1. 实现一个默认的(即无参数的)构造方法(constructor)...

    springmybatis

    IUserOperation userOperation=session.getMapper(IUserOperation.class); User user = userOperation.selectUserByID(1); System.out.println(user.getUserAddress()); System.out.println(user.getUserName())...

Global site tag (gtag.js) - Google Analytics