一点Hibernate + spring 使用经验

 
以前单独用Hibernate2.0的时候,为了保证一个线程中每次取出的session都是一个对象,就使用官方提供的一个HibernateUtils,将第一次取出的session放入ThreadLocal中,以后每次从这里面取出的session都是一个对象,可以保证事务的正常执行。
后来升级到3.0,也这样延用下去,没怎么关心3.0的新特性。
前几天想将Hibernate加入到SPRING的事务管理中,但是我又不想使用spring提供的HibernateDaoSupport或HibernateTemplate,只想像以前那样在一个线程中的任意地方都能得到同一个session。这样就出问题了,spring管理事务的话,如果要保证当前线程内只有一个session,需要将sessionFactory传递给org.springframework.orm.hibernate3.HibernateTransactionMana ger,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的配置文件中加入了<property name="current_session_context_class">thread</property>,又运行,还是出同样的错误。继续上网上查资料,基本没有相关资料。后来费了好大劲才发现,原来在hibernate3.0里只能和jta绑定,我copy了新的3.2的包,这下可以了。不出那个事务管理的错了,变成了org.hibernate.HibernateException: save is not valid without active transaction错误。继续搜,只有一个相关资料,说使用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,在做数据库操作时必须在事务中做,包括只读的查询,否则会报错。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值