hibernate中获取session和开启事务时遇到问题及解决

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/name_z/article/details/54809195

代码 是在spring+hibernate框架下

获取session

方法:

protected SessionFactory sessionFactory;
...
Session session = this.sessionFactory.getCurrentSession();

通过调用SessionFactory的getCurrentSession()方法

出现的异常:

org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread

解决:

配置文件中必须配置hibernate.current_session_context_class选项为thread:

<bean id="sessionFactory"
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />

        <property name="hibernateProperties">
            <props>
                <!-- 配置不同数据库的方言 -->
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
                <prop key="hibernate.hbm2ddl.auto">update</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hiberante.format_sql">true</prop>
                <!-- 一定要配置为thread -->
                <prop key="hibernate.current_session_context_class">thread</prop>
            </props>
        </property>

        <!-- 自动扫描制定位置下的实体进行映射 -->
        <property name="packagesToScan" value="com.bean" />
    </bean>

使用getCurrentSession获取的session开启事务

方法:

session.beginTransaction();

出现的异常:

org.hibernate.TransactionException: nested transactions not supported

出现场景:

每次调用getCurrentSession()后都要调用beginTransaction()开启事务。这时,当连续进行查询事务,从而导致连续的事务开启
例子:

    Tag tag = new Tag();
    tag.setTag("test");
    //调用getCurrentSession(),获取的session再掉用beginTransaction()
    tag = tagDao.getByTagName(tag);

    Account account = new Account();
    account.setName("cat");
    //调用getCurrentSession(),获取的session再掉用beginTransaction()
    account = accountDao.getByName(account);

解决方法:

从异常信息(nested transactions not supported)中即可看出是异常原因是,第二次获取的session已经开启了事务,但是又一次调用beginTransaction()开启事务,从而导致异常。
所以,我想出的解决方法是通过捕抓异常:

    //其它调用SessionFactory自身的getCurrentSession方法时,全都改为下面自己写的getCurrentSession()方法
    /**
     * 获取开启事务后的session
     * 
     * @return
     */
    protected Session getCurrentSession() {
        Session session = this.sessionFactory.getCurrentSession();
        try {
            session.beginTransaction();
        } catch (TransactionException e) {

        }
        return session;
    }

    ...
    ...(){
        Session session = this.getCurrentSession();
        Query query = session.createQuery(hql);
    }

猜你喜欢

转载自blog.csdn.net/name_z/article/details/54809195
今日推荐