When getCurrentSession is used in Hibernate4 to report cocould not obtain transaction-synchronized Session for current thread, synchronizedsession

Source: Internet
Author: User

When getCurrentSession is used in Hibernate4 to report cocould not obtain transaction-synchronized Session for current thread, synchronizedsession

Assume a spring4 + hibernate4 demo, inject sessionFactory directly into the dao layer, and then use the getCurrentSession method to get the session. Then the problem arises and an error is reported:

Could not obtain transaction-synchronized Session for current thread

The system prompts that the transaction synchronization session of the current thread cannot be obtained. This is slightly strange. What is the relationship with the event .. then Baidu said it would be better to use the openSession method. Then I tried Baidu again to see the differences between the two methods:

(1) openSession is a new Session every time it is opened, so the Session instances obtained multiple times are different, and the Session must be closed manually by calling the close method. (2) getCurrentSession obtains the Session from the current context and is bound to the current thread. A Session instance will be created during the first call. If the Session is not closed, the same Session instance will be obtained multiple times. Sesison will be automatically closed when the transaction is committed or rolled back, without manual shutdown.

It seems that the getCurrentSession method is indeed related to the transaction. Then I add the transaction:

    <bean id="transactionManager"        class="org.springframework.orm.hibernate4.HibernateTransactionManager">        <property name="sessionFactory">            <ref bean="sessionFactory" />        </property>    </bean>    <tx:annotation-driven transaction-manager="transactionManager"/>

Then add the @ Transaction annotation to the dao layer and run OK again. But curious, let's take a look at the source code of getCurrentSession (spring implementation class in my demo). The key points are as follows:

if (TransactionSynchronizationManager.isSynchronizationActive()) {            Session session = this.sessionFactory.openSession();            if (TransactionSynchronizationManager.isCurrentTransactionReadOnly()) {                session.setFlushMode(FlushMode.MANUAL);            }            SessionHolder sessionHolder = new SessionHolder(session);            TransactionSynchronizationManager.registerSynchronization(                    new SpringSessionSynchronization(sessionHolder, this.sessionFactory, true));            TransactionSynchronizationManager.bindResource(this.sessionFactory, sessionHolder);            sessionHolder.setSynchronizedWithTransaction(true);            return session; } else {            throw new HibernateException("Could not obtain transaction-synchronized Session for current thread"); }

Then, click it to view the isSynchronizationActive () method:

public static boolean isSynchronizationActive() {        return (synchronizations.get() != null);    }

Get method description:

Returns the value in the current thread's copy of this thread-local variable. If the variable has no value for the current thread, it is first initialized to the value returned by an invocation of the initialValue method.

Then let's look at the initialValue description:

This implementation simply returns null; if the programmer desires thread-local variables to have an initial value other than null, ThreadLocal must be subclassed, and this method overridden. Typically, an anonymous inner class will be used.

Now the problem is clear. To add one point, the transaction is configured in the configuration file, but it is the method that defines transaction propagation according to the method name in the configuration, but it is not inherited in dao, therefore, there is actually no transaction, only the implementation. in spring's transaction implementation, You need to determine whether the transactions in the current thread are synchronized, but when there is no transaction, the method to determine whether to synchronize will return false because get returns the initial null value, eventually throw a cocould not obtain transaction-synchronized Session for current thread exception.

In summary, spring4 + hibernate4 requires transaction configuration when using the hibernate api. if the transaction is not configured, an exception is thrown when obtaining the current session.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.