No qualifying bean of type [javax.persistence.EntityManage] 异常问题的解决
来源:互联网 发布:和平典范 知乎 编辑:程序博客网 时间:2024/04/28 20:32
引言: 在Spring Web项目中一般都会使用OpenEntityManagerInViewFilter来保证JPA session的正常关闭,在笔者的项目中,使用了Spring + Spring Data + JPA + Hibernate来的架构来组织项目,碰到了org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'entityManagerFactory' is defined 的异常信息,将过一番查找之后,方才发现问题是加载顺序的问题....
1. 项目背景介绍
项目中使用的技术有: Spring+Spring Data, JPA, Hibernate等来贯穿项目的主题架构。
2. Session异常关闭的处理机制
在Java Web项目中使用Hibernate经常会遇到LazyInitializationException 。这是因为controller和model层(java代码)将通过JPA的一些启用了延迟加载功能 的领域(如用getRefrence() 方法或者在关联关系中采用fetch=FetchType.LAZY )返回给view层(jsp代码)的时候,由于加载领域对象的JPA Session已经关闭,导致这些延迟加载的数据访问异常。
这时就可以使用OpenEntityManagerInViewFilter来将一个JPAsession与一次完整的请求过程对应的线程相绑定。
解决办法:
<filter> <filter-name>Spring OpenEntityManagerInViewFilter</filter-name> <filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class> <init-param> <!-- 指定org.springframework.orm.jpa.LocalEntityManagerFactoryBean在spring配置文件中的名称,默认值为entityManagerFactory 如果LocalEntityManagerFactoryBean在spring中的名称不是entityManagerFactory,该参数一定要指定,否则会出现找不到entityManagerFactory的例外 --> <param-name>entityManagerFactoryBeanName</param-name> <param-value>entityManagerFactory</param-value> </init-param> </filter> <filter-mapping> <filter-name>Spring OpenEntityManagerInViewFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>3. 异常问题的出现
在解决了Session异常关闭之后,在启动服务器的时候,就出现了如下异常信息:
org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'entityManagerFactory' is definedat org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:575)at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1111)at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:276)at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195)at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1121)at org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter.lookupEntityManagerFactory(OpenEntityManagerInViewFilter.java:222)at org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter.lookupEntityManagerFactory(OpenEntityManagerInViewFilter.java:205)at org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter.doFilterInternal(OpenEntityManagerInViewFilter.java:150)at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:106)at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:106)at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1040)at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:313)at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)at java.lang.Thread.run(Thread.java:662)从异常信息的分析可知道,OpenEntityManagerInViewFilter中对entityManagerFactory有依赖,需要对其在Spring中声明的实例依赖。 但是没有找到合适的实例。
可是entityManagerFactory的确已经声明在了spring的配置文件之中了。问题在哪里呢?
4. 问题分析以及定位
项目中entityManagerFactory在Spring中的配置文件定义的,经过检查,工作正常,不存在问题。
<beans:bean id="entityManagerFactory"class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"><beans:property name="dataSource" ref="dataSource" /> <!-- <beans:property name="persistenceProviderClass" value="org.hibernate.ejb.HibernatePersistence"/> --><beans:property name="jpaVendorAdapter"><beans:beanclass="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"><!-- hibernate properties definition --></beans:bean></beans:property><beans:property name="persistenceUnitName" value="myPersistenceUnit" /><beans:property name="packagesToScan"><beans:list><beans:value>com.creditease.bsettle.pay.model</beans:value></beans:list></beans:property><beans:property name="loadTimeWeaver"><beans:beanclass="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" /></beans:property><beans:property name="jpaPropertyMap"><beans:map><beans:entry key="showSql" value="true"></beans:entry><beans:entry key="generateDdl" value="false"></beans:entry><beans:entry key="hibernate.format_sql" value="true"></beans:entry><beans:entry key="hibernate.dialect"value="org.hibernate.dialect.Oracle10gDialect"></beans:entry></beans:map></beans:property></beans:bean>于是把问题的怀疑点聚焦在web.xml初始化文件上,是否其中存在什么问题呢?
在web.xml中存在2个地方进行spring实例的初始化操作:
<context-param><param-name>contextConfigLocation</param-name><param-value>classpath:META-INF/spring-config.xml</param-value></context-param>第二个位置是:
<servlet><servlet-name>appServlet</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:META-INF/applicationContext.xml</param-value></init-param><load-on-startup>1</load-on-startup></servlet>存在错误异常的加载顺序中,entityManagerFactory是在第二个位置中进行加载的。但是OpenEntityManagerInViewFilter是否加载的顺序在其之前,然后就造成了这样的问题呢?
经过试验,果然是加载顺序的问题,将数据库加载的顺序提前即可。
5. 总结
基于上面的问题,我们可以看到, OpenEntityManagerInViewFilter是在系统启动过程中,优先被加载的,同时其对entityManagerFactory有依赖,就要求同时可以初始化entityManagerFactory的实例。
通过调整初始化的顺序,即可很好的修正上述的问题。
参考资料:
1. http://whoosh.iteye.com/blog/1300721
- No qualifying bean of type [javax.persistence.EntityManage] 异常问题的解决
- 日常-Spring IOC的No qualifying bean of type问题
- junit 测试问题 No qualifying bean of type [javax.servlet.http.HttpServletRequest] found for dependency
- No qualifying bean of type
- No unique bean of type [javax.persistence.EntityManagerFactory] is defined
- 解决“No qualifying bean of type found for dependency”办法
- no qualifying bean of type [...] is define
- springmvc No qualifying bean of type
- NoSuchBeanDefinitionException: No qualifying bean of type
- NoSuchBeanDefinitionException:No qualifying bean of type 解决方法
- No qualifying bean of type [] is defined
- No qualifying bean of type(xxxxxx)
- spring boot+mybatis 多数据源报错 No qualifying bean of type [javax.sql.DataSource] is defined:
- javax.persistence.PersistenceException: No Persistence provider for EntityManage
- Bean对象注入失败 .NoSuchBeanDefinitionException: No qualifying bean of type..
- No qualifying bean of type 'com.yubai.bean.BeanWayService' available
- 解决:No qualifying bean of type [org.springframework.jdbc.core.JdbcTemplate] found for dependency
- No qualifying bean of type [services.ExportService] found for dependency问题原因
- 1009. 说反话
- android之interpolator的用法详解
- 正则表达式判断手机号码格式是否合法
- 涂鸦数据结构3 算法相关
- 都是分号惹的祸(ORA-00911: invalid character)
- No qualifying bean of type [javax.persistence.EntityManage] 异常问题的解决
- mysql5.5.29绿色版的安装
- Displaying Webform submission data in Drupal Views
- GDI+新建画刷时出现new错误问题
- 设计模式六大原则(2):里氏替换原则
- 【Android 非常基础】ListView分页加载提交的参数分析
- 修改CAS框架源码实现多字段认证单点登录
- makefile调试总结
- Spring Quartz 动态配置定时任务