SSH中使用getCurrentSession()获得session

来源:互联网 发布:护士做网络咨询好不好 编辑:程序博客网 时间:2024/06/07 11:11
  1. 在hibernate的配置文件中增加属性:

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

    如下表红色部分

     

    <hibernate-configuration>

    <session-factory>

       <property name="connection.username">root</property>

       <property name="connection.url">

        jdbc:mysql://localhost:3306/dbtest

       </property>

       <property name="dialect">

        org.hibernate.dialect.MySQLDialect

       </property>

       <property name="myeclipse.connection.profile">dbtest</property>

       <property name="connection.password">123456</property>

       <property name="connection.driver_class">

        com.mysql.jdbc.Driver

       </property>

       <property name="show_sql">true</property>

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

       <mapping resource="com/pc386/hibernate/entity/User.hbm.xml" />

     

    </session-factory>

    </hibernate-configuration>

  2. 在SSH中,如果把hibernate交给Spring的管理事物中,那么应该修改Spring的配置文件applicationContext.xml文件的属性,在sessionFactory的属性中增加: <propkey="current_session_context_class">thread</prop>bean id="sessionFactory"

    class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">

    <property name="dataSource">

       <ref local="dataSource"/>

    </property>

    <property name="mappingResources">

       <list>

        <value>User.hbm.xml </value>

       </list>

    </property>

    <property name="hibernateProperties">

       <props>

        <prop key="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</prop>

    <!--

        <prop key="hibernate.transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</prop>

    -->

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

       </props>

    </property>

    </bean>

  3. 原文出处
    1. http://blog.csdn.net/daryl715/archive/2007/02/11/1507385.aspx

      No CurrentSessionContext configured!" 异常解决方案

      hibernate 老说没有配方言

      <property name="dialect">org.hibernate.dialect.MySQLDialect</property>

      这句话明明就写在了配置文件里面,可老是没有写

      错误如下:

      Exception in thread "main" org.hibernate.HibernateException: Hibernate Dialect must be explicitly set

      name改成"hibernate.dialect"也不行

      Hibernate-Version: 3.1.1

      mysql -Verison: 4.0.16

      用这种方法正确

      static {

      try {

      configuration = new Configuration();

      sessionFactory = configuration.configure().buildSessionFactory();

      } catch (Throwable ex) {

      throw new ExceptionInInitializerError(ex);

      }

      }

      这种方式会出现异常

      // static {

      // try {

      // // Create a configuration based on the properties file we've put

      // Configuration config = new Configuration();

      // config.addClass(Customer.class).addClass(Order.class);

      // // Get the session factory we can use for persistence

      // sessionFactory = config.buildSessionFactory();

      // } catch (Exception e) {

      // e.printStackTrace();

      // }

      // }

      第二种方式是针对使用properties文件配置hiernate的写法,使用hibernate.cfg.xml应使用第一种调用方式

      或者在hibernate.cfg.xml中加入:

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

    2. http://blog.sina.com.cn/s/blog_412d58ec010005p5.html

      以前单独用Hibernate2.0的时候,为了保证一个线程中每次取出的session都是一个对象,就使用官方提供的一个HibernateUtils,将第一次取出的session放入ThreadLocal中,以后每次从这里面取出的session都是一个对象,可以保证事务的正常执行。

      后来升级到3.0,也这样延用下去,没怎么关心3.0的新特性。

      前几天想将Hibernate加入到SPRING的事务管理中,但是我又不想使用spring提供的HibernateDaoSupport或HibernateTemplate,只想像以前那样在一个线程中的任意地方都能得到同一个session。这样就出问题了,spring管理事务的话,如果要保证当前线程内只有一个session,需要将sessionFactory传递给org.springframework.orm.hibernate3.HibernateTransactionManager,spring负责事务的开始,提交,回滚以及session的关闭,假设spring用于管理事务的session是(session1)。如果我还用HibernateUtils.getCurrentSession()方法获得session的话,得到的session却是(session2),和开始事务的session不是同一个对象,就造成session2的事务没有提交,对数据库的操作无效。

      后来搜索到原来Hibernate3.0以后,sessionFactory多了个新的方法getCurrentSession()。我心里很高兴,这样不就解决我的问题了吗?

      于是我就将HibernateUtils中的session=sessionFactory.openSession()方法改为了session=sessionFactory.getCurrentSession().

      运行测试竟然错了,

      提示什么TransactionManager出错了,上网上搜了搜,原来使用getCurrent方法必须配置事务管理,需要和jta或thread绑定。我不想用jta,当然要和线程绑定了。我在hibernate的配置文件中加入了<propertyname="current_session_context_class">thread</property>,又运行,还是出同样的错误。继续上网上查资料,基本没有相关资料。后来费了好大劲才发现,原来在hibernate3.0里只能和jta绑定,我copy了新的3.2的包,这下可以了。不出那个事务管理的错了,变成了org.hibernate.HibernateException: save is notvalid without activetransaction错误。继续搜,只有一个相关资料,说使用getCurrentSession()方法必须在事务中运行。不管查询还是更新操作都要开始事务,操作,提交事务才行。

      可是我已经配置了让spring管理事务,为什么出这个错误?看来只有一个原因,spring在通过sessionFactory获取session时,没有调用getCurrentSession()方法。

      自己手动加入事务的开始,提交,成功了。

      经过多次实验,发现,只能能spring中配置sessionFactory,才能让spring管理hibernate的事务。

      <bean id="sessionFactory"

      class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">

      <property name="dataSource">

         <ref local="dataSource"/>

      </property>

      <property name="mappingResources">

         <list>

          <value>User.hbm.xml </value>

         </list>

      </property>

      <property name="hibernateProperties">

         <props>

          <prop key="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</prop>

      <!--

          <prop key="hibernate.transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</prop>

      -->

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

         </props>

      </property>

      </bean>

      在程序中要用到session的时候,过程如下 :

      UserDAOImpl:

      {

      SessionFactory sf = [从spring中得到sessionFactory];

      Session session = sf.getCurrentSession();

      //数据库操作

      }

      这么乱。写一下总结。

      1. 如果想让spring帮你管理事务,只能在spring中配置SessionFactory。如果使用hibernate原有的sessionFactory,则只能自己手动管理事务。

      2. 如果想使用sessionFactory.getCurrentSession()方法,必须配置sessionFactory和jta或thread绑定。但是hibernate3.0不支持与thread绑定,3.1以上才支持。

      3. sessionFactory.getCurrentSession()方法取得的session,在做数据库操作时必须在事务中做,包括只读的查询,否则会报错。

原创粉丝点击