我重构了我的服务层以作为通用组件工作。之后,我的控制器的所有请求都开始抛出org.hibernate.HibernateException:没有Hibernate Session绑定到线程,并且配置不允许在这里创建非事务性的。
我在互联网上搜索并找到了常见的原因:
但似乎没有一个与我的案件有关。
我很感激任何帮助,因为我花了这么多时间来处理这个例外。
堆栈跟踪
[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
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;
}
}
通用服务界面
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);
}
通用服务实施
@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();
}
具体服务界面
public interface InfoJournalService extends AbstractCRUDService<InfoJournalEntry, Long> }
具体服务实施
@Service("infoJournalService")
public class InfoJournalServiceImpl extends AbstractCRUDServiceBean<InfoJournalEntry, Long> implements InfoJournalService {
@Autowired
private InfoJournalDao infoJournalDao;
@Override
public AbstractDao<InfoJournalEntry, Long> getDao() {
return infoJournalDao;
}
}
通用DAO界面
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();
}
通用DAO实施 公共抽象类HibernateGenericDao实现了AbstractDao {
@Autowired
protected SessionFactory sessionFactory;
//....
@SuppressWarnings("unchecked")
public List<E> findAll() {
return sessionFactory.getCurrentSession().createCriteria(getEntityClass()).list();
}
public abstract Class getEntityClass();
}
具体的DAO实施
@Repository("infoJournalDao")
public class InfoJournalDaoImpl extends HibernateGenericDao<InfoJournalEntry, Long> implements InfoJournalDao {
@Override
public Class getEntityClass() {
return InfoJournalEntry.class;
}
}
根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>
答案 0 :(得分:7)
我似乎发现了自己的错误。
root-context.xml
和servlet-context.xml
都包含相同的行<context:component-scan base-package="ru.centr_in.rescuer.server" />
。
现在我按以下方式指定了基础包:
<强>根context.xml中强>
<context:component-scan base-package="ru.centr_in.rescuer.server.service" />
<context:component-scan base-package="ru.centr_in.rescuer.server.dao" />
和 servlet-context.xml
<context:component-scan base-package="ru.centr_in.rescuer.server.web" />
现在一切正常。
的Miles答案 1 :(得分:0)
Spring建议您只使用@Transactional
注释来注释具体类(以及具体类的方法),而不是注释接口。
您是否尝试将@Transactional
注释放在InfoJournalServiceImpl
课程上?另外,您是否检查过弹簧配置中有<tx:annotation-driven transaction-manager="..." />
,如the Spring documentation中所述?