Problem with transactions: No Hibernate Session bound to thread
It seems I've found my mistake.
Both root-context.xml
and servlet-context.xml
contain the same line <context:component-scan base-package="ru.centr_in.rescuer.server" />
.
Now I specified base packages in the following way:
root-context.xml
<context:component-scan base-package="ru.centr_in.rescuer.server.service" />
<context:component-scan base-package="ru.centr_in.rescuer.server.dao" />
and servlet-context.xml
<context:component-scan base-package="ru.centr_in.rescuer.server.web" />
And now everything works.
Thanks to Miles from Entities Not Persisting - Spring + Hibernate + JPA
Nofate
Updated on June 15, 2022Comments
-
Nofate almost 2 years
I refactored my service layer to work as generic component. After that all request to my controller began to throw org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here.
I searched over the internet and found common reasons:
- Lack of @Transaction annotation.
- Usage of hibernate.current_session_context_class and hibernate.transaction_factory_class options.
- Direct calls to sessionFactory.openSession().
- Using BeanFactory instead of ApplicationContext.
- Several instances of DAO class.
But it seems that none of them are related to my case.
I would appreciate any help as I've spent all my day with this exception.
Stacktrace
[INFO] 2011-08-12 15:42:49,383 [btpool0-0] INFO ru.centr_in.rescuer.server.web.InfoJournalController - FETCH started: all [INFO] 2011-08-12 15:42:49,383 [btpool0-0] DEBUG org.springframework.orm.hibernate3.SessionFactoryUtils - Opening Hibernate Session [INFO] 2011-08-12 15:42:49,383 [btpool0-0] DEBUG org.hibernate.impl.SessionImpl - opened session at timestamp: 13131493693 [INFO] 2011-08-12 15:42:49,383 [btpool0-0] DEBUG org.springframework.orm.hibernate3.SessionFactoryUtils - Closing Hibernate Session [INFO] 2011-08-12 15:42:49,383 [btpool0-0] DEBUG org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver - Resolving exception from handler [ru.centr_in.rescuer.server.web.InfoJournalController@14e1b74]: org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here [INFO] 2011-08-12 15:42:49,384 [btpool0-0] DEBUG org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver - Resolving exception from handler [ru.centr_in.rescuer.server.web.InfoJournalController@14e1b74]: org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here [INFO] 2011-08-12 15:42:49,384 [btpool0-0] DEBUG org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver - Resolving exception from handler [ru.centr_in.rescuer.server.web.InfoJournalController@14e1b74]: org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here [INFO] 2011-08-12 15:42:49,384 [btpool0-0] DEBUG org.springframework.web.servlet.DispatcherServlet - Could not complete request [INFO] org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here [INFO] at org.springframework.orm.hibernate3.SpringSessionContext.currentSession(SpringSessionContext.java:63) [INFO] at org.hibernate.impl.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:574) [INFO] at ru.centr_in.rescuer.server.dao.HibernateGenericDao.findAll(HibernateGenericDao.java:41) [INFO] at ru.centr_in.rescuer.server.service.AbstractCRUDServiceBean.findAll(AbstractCRUDServiceBean.java:21) [INFO] at ru.centr_in.rescuer.server.web.InfoJournalController.getInfoJournalEntries(InfoJournalController.java:40) [INFO] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [INFO] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) [INFO] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) [INFO] at java.lang.reflect.Method.invoke(Method.java:597) [INFO] at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:176) [INFO] at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:426) [INFO] at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:414) [INFO] at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:790) [INFO] at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719) [INFO] at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644) [INFO] at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:549) [INFO] at javax.servlet.http.HttpServlet.service(HttpServlet.java:617) [INFO] at javax.servlet.http.HttpServlet.service(HttpServlet.java:717) [INFO] at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:487) [INFO] at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:362) [INFO] at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216) [INFO] at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181) [INFO] at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:729) [INFO] at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:405) [INFO] at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152) [INFO] at org.mortbay.jetty.handler.RequestLogHandler.handle(RequestLogHandler.java:49) [INFO] at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152) [INFO] at org.mortbay.jetty.Server.handle(Server.java:324) [INFO] at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:505) [INFO] at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:829) [INFO] at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:513) [INFO] at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:211) [INFO] at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:380) [INFO] at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:395) [INFO] at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:488)
Controller
@Controller public class InfoJournalController { @Autowired private InfoJournalService infoJournalService; @RequestMapping(value="/infoJournal", method=RequestMethod.GET) public @ResponseBody InfoJournalEntry[] getInfoJournalEntries() { List<InfoJournalEntry> entries = infoJournalService.findAll(); InfoJournalEntry[] result = new InfoJournalEntry[entries.size()]; entries.toArray(result); return result; } }
Generic service interface
public interface AbstractCRUDService<E, PK extends Serializable> { void save(E entity); List<E> findAll(); E findById(PK id); void delete(E entity); void update(E entity); }
Generic service implementation
@Transactional public abstract class AbstractCRUDServiceBean<E, PK extends Serializable> implements AbstractCRUDService<E, PK> { //.... @Transactional public List<E> findAll() { return getDao().findAll(); } //.... public abstract AbstractDao<E, PK> getDao(); }
Concrete service interface
public interface InfoJournalService extends AbstractCRUDService<InfoJournalEntry, Long> }
Concrete service implementation
@Service("infoJournalService") public class InfoJournalServiceImpl extends AbstractCRUDServiceBean<InfoJournalEntry, Long> implements InfoJournalService { @Autowired private InfoJournalDao infoJournalDao; @Override public AbstractDao<InfoJournalEntry, Long> getDao() { return infoJournalDao; } }
Generic DAO interface
public abstract class HibernateGenericDao<E, PK extends Serializable> implements AbstractDao<E, PK> { @Autowired protected SessionFactory sessionFactory; //.... @SuppressWarnings("unchecked") public List<E> findAll() { return sessionFactory.getCurrentSession().createCriteria(getEntityClass()).list(); } public abstract Class getEntityClass(); }
Generic DAO implementation public abstract class HibernateGenericDao implements AbstractDao {
@Autowired protected SessionFactory sessionFactory; //.... @SuppressWarnings("unchecked") public List<E> findAll() { return sessionFactory.getCurrentSession().createCriteria(getEntityClass()).list(); } public abstract Class getEntityClass(); }
Concrete DAO implementation
@Repository("infoJournalDao") public class InfoJournalDaoImpl extends HibernateGenericDao<InfoJournalEntry, Long> implements InfoJournalDao { @Override public Class getEntityClass() { return InfoJournalEntry.class; } }
root-context.xml
<context:annotation-config /> <context:component-scan base-package="ru.centr_in.rescuer.server" /> <import resource="datasource.xml" />
datasource.xml
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager" > <property name="sessionFactory" ref="sessionFactory" /> </bean> <tx:annotation-driven transaction-manager="transactionManager"/> <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="location"> <value>WEB-INF/database.properties</value> </property> </bean> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="${jdbc.driverClassName}" /> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </bean> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="configurationClass"> <value>org.hibernate.cfg.AnnotationConfiguration</value> </property> <property name="hibernateProperties"> <props> <prop key="hibernate.show_sql">true</prop> <prop key="hibernate.hbm2ddl.auto">create</prop> <prop key="hibernate.dialect">${jdbc.dialect}</prop> <prop key="hibernate.connection.charset">UTF-8</prop> </props> </property> <property name="annotatedClasses"> <list> <value>ru.centr_in.rescuer.server.domain.InfoJournalEntry</value> </list> </property> </bean>
servlet-context.xml
<annotation-driven/> <context:component-scan base-package="ru.centr_in.rescuer.server" /> <resources mapping="/resources/**" location="/resources/"/> <resources mapping="/Rescuer.html" location="/Rescuer.html"/> <resources mapping="/Rescuer/**" location="/Rescuer/"/> <beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <beans:property name="prefix" value="/WEB-INF/views/"/> <beans:property name="suffix" value=".jsp"/> </beans:bean>
-
Nofate over 12 yearsYes, annotating
InfoJournalServiceImpl
does not help. Yes, my config containstx:annotation-driven
.