SpringMVC 4 + Hibernate 4启动完成调用Service报错No Session found for current thread

卡F 2017-04-01 02:51:40
我为服务添加了onApplicationEvent来响应服务加载完成事件。
并在事件中做一些初始化,初始化中有数据库操作,会报No Session found for current thread错误。麻烦帮忙看下。

错误:

严重: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
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:988)
at com.ddm.core.base.dao.BaseDaoImpl.getSession(BaseDaoImpl.java:47)
at com.ddm.core.base.dao.BaseDaoImpl.getCriteria(BaseDaoImpl.java:61)
at com.ddm.core.base.dao.BaseDaoImpl.find(BaseDaoImpl.java:80)
at com.ddm.core.base.dao.BaseDaoImpl.find(BaseDaoImpl.java:69)
at com.ddm.core.base.dao.BaseDaoImpl.findAll(BaseDaoImpl.java:65)
at com.ddm.core.base.service.BaseServiceImpl.list(BaseServiceImpl.java:56)
at com.ddm.core.base.service.BaseServiceImpl$$FastClassBySpringCGLIB$$59e55cef.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:708)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:644)
at com.ddm.core.service.ModuleService$$EnhancerBySpringCGLIB$$554969ac.list(<generated>)
at com.ddm.core.utils.PermissionUtil.updatePermission(PermissionUtil.java:73)
at com.ddm.core.listener.StartupListener.updatePermission(StartupListener.java:31)
at com.ddm.core.listener.StartupListener.onApplicationEvent(StartupListener.java:23)
at com.ddm.core.listener.StartupListener.onApplicationEvent(StartupListener.java:1)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:98)
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:333)
at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:776)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:485)
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:403)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:306)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:106)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4853)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5314)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1408)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1398)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
...全文
298 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
卡F 2017-04-05
  • 打赏
  • 举报
回复
感谢大家热情的解答!我知道问题出现在哪里了!现在做出解答。 我的Service层都继承了一个基类BaseService。这个BaseService类中有很多通用的数据库操作。因为aop切点没有切到这个地方,所以老会出错。最后把切点配置给改了,然后就OK了,下面是代码。再次感谢大家! spring-hibernate.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
// .....Other code ignored
      
    <!-- 配置AOP切面 -->  
    <aop:config proxy-target-class="true">  
        <aop:pointcut id="transactionPointcut" expression="execution(* com.ddm.core.service..*.*(..))" />  
        <aop:advisor pointcut-ref="transactionPointcut" advice-ref="transactionAdvice" />  
    </aop:config> 
</beans>
spring-hibernate.xml 修改后
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
// .....Other code ignored
      
    <!-- 配置AOP切面 -->  
    <aop:config proxy-target-class="true">  
        <aop:pointcut id="transactionPointcut" expression="
        	(execution(* com.ddm.core.service..*.*(..))) or
        	(execution(* com.ddm.core.base.service..*.*(..)))" />  
        <aop:advisor pointcut-ref="transactionPointcut" advice-ref="transactionAdvice" />  
    </aop:config> 
</beans>
licip 2017-04-01
  • 打赏
  • 举报
回复
<property name="hibernateProperties"> <props> <prop key="hibernate.dialect"> org.hibernate.dialect.MySQLDialect </prop> <prop key="hibernate.show_sql">true</prop> <prop key="hibernate.format_sql">true</prop> <prop key="hibernate.current_session_context_class">thread</prop> </props> </property>
  • 打赏
  • 举报
回复
卡F 2017-04-01
  • 打赏
  • 举报
回复
这个是权限控制的一个工具类。在服务初始化的时候会进行权限控制Controller的收集工作。如果我把这个方法内容注释掉则不会有问题。这个updatePermission()方法的调用时机就是springMVC 的onApplicationEvent。 PermissionUtil.java
	
	/**
	 * 更新permission信息
	 */
	@Transactional
	public static void updatePermission(ApplicationContextEvent evt) {
		ModuleService moduleService = (ModuleService) SpringUtils.getBean("moduleService");
		// 只有Controller才会被认为需要进行权限验证
		Map<String, Object> beans = evt.getApplicationContext().getBeansWithAnnotation(Controller.class);
		Set<String> keys = beans.keySet();
		List<Module> allModule = moduleService.list();
		for(String key : keys) {
			// 获取类实例
			Object clazz = beans.get(key);
			// 声明父映射路径,如果有
			String[] pMapping = {};
			String gName = null;
			Permission pClazz = clazz.getClass().getAnnotation(Permission.class);
			if(null != pClazz) {
			    gName = pClazz.name();
				pMapping = clazz.getClass().getAnnotation(RequestMapping.class).value();
			}
			// 通过反射机制获取Bean的所有方法
			Method[] methods = clazz.getClass().getMethods();
			for(Method method : methods) {
				// 获取方法的Permission注解信息,如果有
				Permission ann = method.getAnnotation(Permission.class);
				// 获取方法的RequestMapping注解信息,如果有
				RequestMapping mCtrler = method.getAnnotation(RequestMapping.class);
卡F 2017-04-01
  • 打赏
  • 举报
回复
引用 10 楼 qnmdcsdn 的回复:
web中配上opensessioninviewfilter试试
	<filter>
		<filter-name>hibernateFilter</filter-name>
		<filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class>
	</filter>
是这个吧!有的!
卡F 2017-04-01
  • 打赏
  • 举报
回复
引用 9 楼 my_God_sky 的回复:
给你附上传送门 传送门
我这Listener中进行了判断,现在确实是调用一次!好像跟这个没有关系。
  • 打赏
  • 举报
回复
web中配上opensessioninviewfilter试试
_南天北落 2017-04-01
  • 打赏
  • 举报
回复
给你附上传送门 传送门
李德胜1995 2017-04-01
  • 打赏
  • 举报
回复
引用 6 楼 b7995547 的回复:
[quote=引用 5 楼 pany1209 的回复:] [quote=引用 2 楼 b7995547 的回复:] [quote=引用 1 楼 pany1209 的回复:] Hibernate文件中配置

<property name="current_session_context_class">thread</property>
在操作数据库的地方使用事务。。。例如 @Transactional注解
报错了呢?是我写的不对吗?[/quote] 我说的是单独的hibernate文件。。。你这个要在prop里面配置吧[/quote] 没太理解,是说在hibernateProperties里面配置吗?[/quote] 因为这个配置是属于Hibernate配置的。。。。所以要陪在hibernateProperties里面
卡F 2017-04-01
  • 打赏
  • 举报
回复
这个错误我理解的是在我调用Session操作数据库的时候,Session还没有被创建好。所以导致错误?不知道理解的对不对!
卡F 2017-04-01
  • 打赏
  • 举报
回复
引用 5 楼 pany1209 的回复:
[quote=引用 2 楼 b7995547 的回复:] [quote=引用 1 楼 pany1209 的回复:] Hibernate文件中配置

<property name="current_session_context_class">thread</property>
在操作数据库的地方使用事务。。。例如 @Transactional注解
报错了呢?是我写的不对吗?[/quote] 我说的是单独的hibernate文件。。。你这个要在prop里面配置吧[/quote] 没太理解,是说在hibernateProperties里面配置吗?
李德胜1995 2017-04-01
  • 打赏
  • 举报
回复
引用 2 楼 b7995547 的回复:
[quote=引用 1 楼 pany1209 的回复:] Hibernate文件中配置

<property name="current_session_context_class">thread</property>
在操作数据库的地方使用事务。。。例如 @Transactional注解
报错了呢?是我写的不对吗?[/quote] 我说的是单独的hibernate文件。。。你这个要在prop里面配置吧
卡F 2017-04-01
  • 打赏
  • 举报
回复
引用 3 楼 my_God_sky 的回复:
谢邀 你初始化数据那一块的注入是否有问题,basedao所在的包是否包含在你的注入包下面。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:c="http://www.springframework.org/schema/c" xmlns:cache="http://www.springframework.org/schema/cache" xmlns:context="http://www.springframework.org/schema/context" xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:lang="http://www.springframework.org/schema/lang" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:p="http://www.springframework.org/schema/p" xmlns:task="http://www.springframework.org/schema/task" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:util="http://www.springframework.org/schema/util"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
		http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
		http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
		http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd
		http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang.xsd
		http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
		http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
		http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
		
	<!-- 这种加载方式可以在代码中通过@Value注解进行注入,可以将配置整体赋给Properties类型的类变量,也可以取出其中的一项赋值给String类型的类变量 -->
<!-- 		<util:properties id="frontSettings" location="classpath:front.properties" /> -->

	<!-- 引入项目配置文件 -->
	<!-- <context:property-placeholder location="classpath:config.properties" /> -->
	<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
		<property name="locations">
			<list>
				<value>classpath:config.properties</value>
			</list>
		</property>
	</bean>

	<!-- 自动扫描repository和service包(自动注入) -->
 	<context:component-scan base-package="com.ddm.core.dao" />
 	<context:component-scan base-package="com.ddm.core.service" />
	
	<!-- springMVC启动完成监听,出问题的调用是在这里面发生的。我在服务启动后进行了写初始化。
初始化的过程需要用到Service,Service中用Dao访问了数据库,在sessionFactory.getCurrentSession()的时候产生了错误。
 -->
	<bean class="com.ddm.core.listener.StartupListener" />
</beans>
_南天北落 2017-04-01
  • 打赏
  • 举报
回复
谢邀 你初始化数据那一块的注入是否有问题,basedao所在的包是否包含在你的注入包下面。
卡F 2017-04-01
  • 打赏
  • 举报
回复
引用 1 楼 pany1209 的回复:
Hibernate文件中配置

<property name="current_session_context_class">thread</property>

在操作数据库的地方使用事务。。。例如 @Transactional注解


报错了呢?是我写的不对吗?
李德胜1995 2017-04-01
  • 打赏
  • 举报
回复
Hibernate文件中配置

<property name="current_session_context_class">thread</property>
在操作数据库的地方使用事务。。。例如 @Transactional注解

81,095

社区成员

发帖
与我相关
我的任务
社区描述
Java Web 开发
社区管理员
  • Web 开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧