My problem is hidden in class, with 2 methods.
@Repository
@Transactional(isolation = Isolation.READ_COMMITTED)
public class RetentionController {
@Autowired
private SessionFactory sessionFactory;
...
@Transactional(readOnly = true)
public BaseResource getResource(String pPath)throws ResourceNotFoundException{
...
Criteria critDirExists = sessionFactory.getCurrentSession().createCriteria(Directory.class);
critDirExists.add(Restrictions.eq(PATH, pPath));
Directory dir = (Directory) critDirExists.uniqueResult();
...processing results...
}
@Transactional(readOnly = false)
public void addDirectory(String pPath) {
modelValidator.validateDirectoryURI(pPath);
//check if such exists
Criteria critExists = sessionFactory.getCurrentSession().createCriteria(Directory.class);
critExists.add(Restrictions.eq("path", pPath));
...
}
...
}
SessionFactory is injected correctly – first method executes normally. The problem is:
addDirectory throws “No Hibernate Session bound to thread” at ” Criteria critExists = sessionFactory.getCurrentSession().createCriteria(Directory.class);”, when it is invoked after “getResource()” method.
Logs (I added marks to see where methods are started and finished: GET RESOURCE: START/END, ADD DIRECTORY: START/END):
DEBUG [org.springframework.beans.factory.support.DefaultListableBeanFactory] - Returning cached instance of singleton bean 'transactionManager'
DEBUG [org.springframework.orm.hibernate3.HibernateTransactionManager] - Creating new transaction with name [com.asg.tciclientadapters.webdav.dal.RetentionController.getResource]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT,readOnly; ''
DEBUG [org.springframework.orm.hibernate3.HibernateTransactionManager] - Opened new Session [org.hibernate.impl.SessionImpl@1be3bb2] for Hibernate transaction
DEBUG [org.springframework.orm.hibernate3.HibernateTransactionManager] - Preparing JDBC Connection of Hibernate Session [org.hibernate.impl.SessionImpl@1be3bb2]
DEBUG [org.springframework.jdbc.datasource.DataSourceUtils] - Setting JDBC Connection [jdbc:sqlserver://******\****:****;selectMethod=direct;lastUpdateCount=true;, UserName=*********, Microsoft SQL Server 2005 JDBC Driver] read-only
DEBUG [org.springframework.orm.hibernate3.HibernateTransactionManager] - Exposing Hibernate transaction as JDBC transaction [jdbc:sqlserver://******\****:****;selectMethod=direct;lastUpdateCount=true;, UserName=*********, Microsoft SQL Server 2005 JDBC Driver]
TRACE [org.springframework.transaction.support.TransactionSynchronizationManager] - Bound value [org.springframework.jdbc.datasource.ConnectionHolder@13b8f62] for key [org.apache.commons.dbcp.BasicDataSource@115512] to thread [http-9080-1]
TRACE [org.springframework.transaction.support.TransactionSynchronizationManager] - Bound value [org.springframework.orm.hibernate3.SessionHolder@299629] for key [org.hibernate.impl.SessionFactoryImpl@1429498] to thread [http-9080-1]
TRACE [org.springframework.transaction.support.TransactionSynchronizationManager] - Initializing transaction synchronization
TRACE [org.springframework.transaction.interceptor.TransactionInterceptor] - Getting transaction for [com.asg.tciclientadapters.webdav.dal.RetentionController.getResource]
DEBUG [org.springframework.beans.factory.support.DefaultListableBeanFactory] - Returning cached instance of singleton bean 'com.asg.tciclientadapters.webdav.aspect.TraceLog#0'
DEBUG [com.asg.tciclientadapters.webdav.dal.RetentionController] - ---GET RESOURCE: START
TRACE [org.springframework.transaction.support.TransactionSynchronizationManager] - Retrieved value [org.springframework.orm.hibernate3.SessionHolder@299629] for key [org.hibernate.impl.SessionFactoryImpl@1429498] bound to thread [http-9080-1]
DEBUG [com.asg.tciclientadapters.webdav.dal.RetentionController] - Getting ILM object: /CADPWebDAV
DEBUG [com.asg.tciclientadapters.webdav.dal.RetentionController] - RequestType is MKCOL
DEBUG [com.asg.tciclientadapters.webdav.dal.RetentionController] - EmbryoResource was created.
TRACE [org.springframework.transaction.support.TransactionSynchronizationManager] - Retrieved value [org.springframework.orm.hibernate3.SessionHolder@299629] for key [org.hibernate.impl.SessionFactoryImpl@1429498] bound to thread [http-9080-1]
DEBUG [com.asg.tciclientadapters.webdav.dal.RetentionController] - ---GET RESOURCE: END
TRACE [com.asg.tciclientadapters.webdav.aspect.TraceLog] - RetentionController.getResource(..) Executed at: 78 ms
TRACE [com.asg.tciclientadapters.webdav.aspect.TraceLog] - Method Argument [1]: com.asg.tciclientadapters.webdav.servlet.CADPRequest@10241ae
TRACE [com.asg.tciclientadapters.webdav.aspect.TraceLog] - Method Argument [2]: com.asg.tciclientadapters.webdav.tci.TCIWrapper@1ca203
TRACE [org.springframework.transaction.interceptor.TransactionInterceptor] - Completing transaction for [com.asg.tciclientadapters.webdav.dal.RetentionController.getResource]
TRACE [org.springframework.orm.hibernate3.HibernateTransactionManager] - Triggering beforeCommit synchronization
TRACE [org.springframework.orm.hibernate3.HibernateTransactionManager] - Triggering beforeCompletion synchronization
DEBUG [org.springframework.orm.hibernate3.HibernateTransactionManager] - Initiating transaction commit
DEBUG [org.springframework.orm.hibernate3.HibernateTransactionManager] - Committing Hibernate transaction on Session [org.hibernate.impl.SessionImpl@1be3bb2]
TRACE [org.springframework.orm.hibernate3.HibernateTransactionManager] - Triggering afterCommit synchronization
TRACE [org.springframework.orm.hibernate3.HibernateTransactionManager] - Triggering afterCompletion synchronization
TRACE [org.springframework.transaction.support.TransactionSynchronizationManager] - Clearing transaction synchronization
TRACE [org.springframework.transaction.support.TransactionSynchronizationManager] - Removed value [org.springframework.orm.hibernate3.SessionHolder@299629] for key [org.hibernate.impl.SessionFactoryImpl@1429498] from thread [http-9080-1]
TRACE [org.springframework.transaction.support.TransactionSynchronizationManager] - Removed value [org.springframework.jdbc.datasource.ConnectionHolder@13b8f62] for key [org.apache.commons.dbcp.BasicDataSource@115512] from thread [http-9080-1]
DEBUG [org.springframework.orm.hibernate3.HibernateTransactionManager] - Closing Hibernate Session [org.hibernate.impl.SessionImpl@1be3bb2] after transaction
DEBUG [org.springframework.orm.hibernate3.SessionFactoryUtils] - Closing Hibernate Session
DEBUG [com.asg.tciclientadapters.webdav.dal.RetentionController] - ---ADD DIRECTORY: START
DEBUG [com.asg.tciclientadapters.webdav.dal.RetentionController] - Validation: OK
DEBUG [org.springframework.orm.hibernate3.SessionFactoryUtils] - Opening Hibernate Session
DEBUG [org.springframework.orm.hibernate3.SessionFactoryUtils] - Closing Hibernate Session
ERROR [com.asg.tciclientadapters.webdav.servlet.CADPServlet] - org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
Spring configuration xml file:
<context:property-placeholder location="classpath:spring.properties"/>
<context:annotation-config/>
<tx:annotation-driven/>
<aop:aspectj-autoproxy/>
<context:mbean-export/>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"
p:driverClassName="${jdbc.driverClassName}"
p:url="${jdbc.url}"
p:username="${jdbc.username}"
p:password="${jdbc.password}"/>
<!-- Hibernate SessionFactory -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"
p:dataSource-ref="dataSource" p:mappingResources="CADPWebDAV_hbm.xml">
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.generate_statistics">${hibernate.generate_statistics}</prop>
<prop key="hibernate.cache.use_structured_entries">true</prop>
</props>
</property>
<property name="eventListeners">
<map>
<entry key="merge">
<bean class="org.springframework.orm.hibernate3.support.IdTransferringMergeEventListener"/>
</entry>
</map>
</property>
</bean>'
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"
p:sessionFactory-ref="sessionFactory"/>
Here is the StackTrace of the exception:
[com.asg.tciclientadapters.webdav.servlet.CADPServlet] - org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
[com.asg.tciclientadapters.webdav.servlet.CADPServlet] - org.springframework.orm.hibernate3.SpringSessionContext.currentSession(SpringSessionContext.java:63)
[com.asg.tciclientadapters.webdav.servlet.CADPServlet] - org.hibernate.impl.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:687)
[com.asg.tciclientadapters.webdav.servlet.CADPServlet] - com.asg.tciclientadapters.webdav.dal.RetentionController.addDirectory(RetentionController.java:189)
...
The solution was – to add into web.xml:
After that exception has gone.