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.