2014-02-13 37 views
0

您好我現在面臨一個很奇怪的問題。我正在使用Spring MVC 3.0 + Spring Security 3.2 + hibernate 4.3。在登錄之前,我可以訪問數據庫並獲取實體的登錄信息。但在春季安全登錄後,我得到例外org.hibernate.HibernateException: No Session found for current thread。這個異常拋出sessionFactory.getCurrentSession()org.hibernate.HibernateException:無會話發現

我已經使用AOP橫斷管理。我的問題是:

登錄後爲什麼會出現問題?雖然它登錄前工作正常嗎?

我的代碼如下:

@Repository("categoryDAO") 
public class CategoryDAOHibernateImpl implements CategoryDAO { 

@Autowired 
SessionFactory sessionFactory; 

public List<Category> findAll() { 
    List<Category> list; 
    try { 
     Session session = sessionFactory.getCurrentSession(); 
     Criteria criteria = session.createCriteria(Category.class); 
     list = criteria.list(); 
    } catch (Exception e) { 
     throw new BookStoreDAORuntimeException(e.getMessage(), e); 
    } 
    return list; 
} 
} 

FullStacktrace:

StandardWrapperValve[appServlet]: Servlet.service() for servlet appServlet threw exception 
org.hibernate.HibernateException: No Session found for current thread 
at org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:106) 
at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:1012) 
at com.abhendra.bookstore.common.entities.dao.hibernate.UserDAOHibernateImpl.findByEmail(UserDAOHibernateImpl.java:68) 
at com.abhendra.bookstore.management.user.impl.UserManagementServiceImpl.findByEmail(UserManagementServiceImpl.java:20) 
at com.abhendra.bookstore.LibreryController.showCategory(LibreryController.java:27) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
at java.lang.reflect.Method.invoke(Method.java:606) 
at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:214) 
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132) 
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104) 
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:748) 
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:689) 
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83) 
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:945) 
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:876) 
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:931) 
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:822) 
at javax.servlet.http.HttpServlet.service(HttpServlet.java:687) 
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:807) 
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790) 
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1682) 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:344) 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214) 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) 
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118) 
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84) 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113) 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103) 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113) 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:154) 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45) 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:199) 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110) 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50) 
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:108) 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87) 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192) 
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160) 
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:344) 
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:261) 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256) 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214) 
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:316) 
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160) 
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:734) 
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:673) 
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99) 
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:174) 
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:357) 
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:260) 
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:188) 
at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:191) 
at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:168) 
at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:189) 
at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119) 
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:288) 
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:206) 
at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:136) 
at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:114) 
at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77) 
at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:838) 
at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:113) 
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:115) 
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:55) 
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:135) 
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:564) 
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:544) 
at java.lang.Thread.run(Thread.java:744) 
]] 

daoContext.xml

<bean id="dataSource" 
    class="org.apache.commons.dbcp.BasicDataSource"> 
    <property name="driverClassName"> 
     <value>org.postgresql.Driver</value> 
    </property> 
    <property name="url"> 
     <value>jdbc:postgresql://localhost:5432/bookstore</value> 
    </property> 
    <property name="username"> 
     <value>bookstore</value> 
    </property> 
    <property name="password"> 
     <value>bookstore</value> 
    </property> 
</bean> 

<bean id="sessionFactory" 
    class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> 
    <property name="dataSource"> 
     <ref bean="dataSource" /> 
    </property> 
    <property name="mappingResources"> 
     <list> 
      <value>Author.hbm.xml</value> 
      <value>Book.hbm.xml</value> 
      <value>Category.hbm.xml</value> 
      <value>Comment.hbm.xml</value> 
      <value>Download.hbm.xml</value> 
      <value>Rating.hbm.xml</value> 
      <value>Role.hbm.xml</value> 
      <value>User.hbm.xml</value> 
     </list> 
    </property> 
    <property name="hibernateProperties"> 
     <value> 
      hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect 
      jdbc.use_getGeneratedKeys=true 
      hibernate.show_sql=true 
      hibernate.hbm2ddl.auto=update 
      hibernate.generate_statistics=false 

      hibernate.cache.use_second_level_cache=false 
      hibernate.cache.use_query_cache=false 
      hibernate.current_session_context_class=org.springframework.orm.hibernate4.SpringSessionContext 
     </value> 
    </property> 

</bean> 

<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"> 
    <property name="sessionFactory"> 
     <ref bean="sessionFactory" /> 
    </property> 
</bean> 

<tx:advice id="defaultTxAdvice" transaction-manager="transactionManager"> 
    <tx:attributes> 
     <tx:method name="get*" read-only="true" propagation="REQUIRED"/> 
     <tx:method name="find*" read-only="true" propagation="REQUIRED"/> 
     <tx:method name="*" /> 
    </tx:attributes> 
</tx:advice> 



<tx:annotation-driven transaction-manager="transactionManager"/> 

<aop:config> 
    <aop:pointcut id="dbServiceOperations" 
     expression="execution(* com.abhendra.bookstore.common.entities.dao.*DAO*.*(..))" /> 
    <aop:advisor pointcut-ref="dbServiceOperations" advice-ref="defaultTxAdvice" /> 
</aop:config> 

SecurityConfig:

<security:http auto-config="false" use-expressions="true"> 
    <security:form-login login-page="/bookstore/authentication/login" 
     login-processing-url="/bookstore/authentication/loginProcess" 
     default-target-url="/bookstore/home/index" 
     authentication-failure-url="/bookstore/authentication/login?login_error=1" /> 
    <!-- authentication-failure-handler-ref="postFailedAuthHandler" --> 
    <security:logout logout-url="/bookstore/authentication/logout" 
     logout-success-url="/bookstore/authentication/login" /> 
    <security:intercept-url pattern="/bookstore/admin/**" access="isAuthenticated()" /> 
    <security:intercept-url pattern="/bookstore/home/**" access="isAuthenticated()" /> 
</security:http> 

<bean id="authenticationProvider" class="com.abhendra.core.spring.security.BookstoreAuthenticationProvider" /> 

<security:authentication-manager alias="authenticationManager" erase-credentials="false"> 
    <security:authentication-provider ref="authenticationProvider"></security:authentication-provider> 
</security:authentication-manager> 

rootContext.xml

<import resource="classpath:daoContext.xml" /> 

<context:component-scan base-package="com.abhendra.bookstore, com.abhendra.core" /> 

的web.xml

<context-param> 
    <param-name>contextConfigLocation</param-name> 
    <param-value>/WEB-INF/spring/root-context.xml, /WEB-INF/spring/appServlet/security-config.xml</param-value> 
</context-param> 

<!-- Creates the Spring Container shared by all Servlets and Filters --> 
<listener> 
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
</listener> 

<!-- Processes application requests --> 
<servlet> 
    <servlet-name>appServlet</servlet-name> 
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 
    <init-param> 
     <param-name>contextConfigLocation</param-name> 
     <param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value> 
    </init-param> 
    <load-on-startup>1</load-on-startup> 
</servlet> 

<filter> 
    <filter-name>springSecurityFilterChain</filter-name> 
    <filter-class> 
     org.springframework.web.filter.DelegatingFilterProxy 
    </filter-class> 
</filter> 

<filter-mapping> 
    <filter-name>springSecurityFilterChain</filter-name> 
    <url-pattern>/bookstore/*</url-pattern> 
    <dispatcher>REQUEST</dispatcher>  
    <dispatcher>FORWARD</dispatcher> 
</filter-mapping> 

<!-- Map all /resources requests to the Resource Servlet for handling --> 
<!-- <servlet-mapping> 
    <servlet-name>Resources Servlet</servlet-name> 
    <url-pattern>/resources/*</url-pattern> 
</servlet-mapping> --> 

<servlet-mapping> 
    <servlet-name>appServlet</servlet-name> 
    <url-pattern>/bookstore/*</url-pattern> 
</servlet-mapping> 

由於事先:-)

+0

你可以發佈完整的堆棧跟蹤,如果太大,你可以使用pastebin.com嗎? –

+0

@jhadesdev添加了StackTrace。 –

回答

0

最後我解決我的問題,而無需增加額外的註解(如@事務)。我在web.xml中添加了這個:

<filter> 
    <filter-name>hibernateFilter</filter-name> 
    <filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class> 
    <init-param> 
     <param-name>sessionFactoryBeanName</param-name> 
     <param-value>sessionFactory</param-value> 
    </init-param> 
</filter> 
<filter-mapping> 
    <filter-name>hibernateFilter</filter-name> 
    <url-pattern>/bookstore/*</url-pattern> 
    <dispatcher>REQUEST</dispatcher> 
    <dispatcher>FORWARD</dispatcher> 
</filter-mapping> 

但我不知道它爲什麼解決和如何。任何人都可以放一些燈嗎?

+1

你有什麼是懶加載的。延遲加載的對象在休眠會話中的DAO中被提取(不完全)。然後它被傳遞給其他不在hib會話中的其他方法(或在您的案例中查看)。當你嘗試訪問延遲加載對象的某些屬性時,hibernate嘗試將選擇語句激發到數據庫,但它不在會話中......你可以閱讀關於hibernate延遲加載的知識,有很多SO問題和關於它的文章那 –

+0

+1瞭解詳情! –

0

嘗試這將有助於:

try { 
     Session session = sessionFactory.getCurrentSession(); 
     session.getTransaction().begin(); 
     Criteria criteria = session.createCriteria(Category.class); 
     list = criteria.list(); 
     session.getTransaction().commit(); 
    } catch (Exception e) { 
     throw new BookStoreDAORuntimeException(e.getMessage(), e); 
    } 
2

的代碼試圖獲得當前會話,但沒有配置@Transactiona l允許容器在調用註釋方法之前向該線程添加會話。

在stacktrace中,我們可以看到LibreryController調用UserManagementServiceImpl,調用UserDAOHibernateImpl,中間沒有事務性代理。

您應該添加對@Transactional的支持,用它來註釋UserManagementServiceImpl並且應該可以解決問題。有關如何執行此操作,請參閱此blog post

+1

不行這個技巧。此代碼在登錄之前完美運行。但登錄後,無法找到會話。我認爲這與春季安全有關,並且由於Spring安全會話,hibernate沒有獲得會話。 –

0

嘗試將@Transactional添加到您的班級。修改您的sessioFactory並添加一個setter:

@Autowired 
@Qualifier("sessionFactory") 
private SessionFactory sessionFactory; 

public void setSessionFactory(SessionFactory sessionFactory) { 
    this.sessionFactory = sessionFactory; 
} 

這是它是如何工作的。如果沒有幫助,嘗試自己打開會話:

private Session session = null; 
private Transaction tx = null; 

public List<Category> findAll() { 
    session = sessionFactory.openSession(); 
    tx = session.beginTransaction(); 
} 
+0

我不想每次打開和關閉會話。我不能使用'sessionFactory.openSession();'。我需要找到'getCurrentSession'的解決方案。請看我自己的解決方案。 –

相關問題