在我们的项目中,最初我们使用的是spring3+hibernate 3最近决定升级第三方jar,作为春季升级到4的一部分,但不升级hibernate(仍然保持hibernate 3)。现在,我们还没有更改spring4升级的任何代码,当我们执行项目LocalContainerEntityManagerFactoryBean时,注入失败了。我已经给出了上下文文件声明&下面的错误堆栈跟踪。现在的问题是,在没有升级hibernate的情况下,我如何使现有项目在spring4上运行。
Spring ORM 4.1.6 LocalContainerEntityManagerFactoryBean试图加载JPA 2.0特定的hibernate导入(即hibernate 4 jar类),但失败了。
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceXmlLocation" value="classpath:META-INF/persistence.xml"/>
<property name="persistenceUnitName" value="casp-portal"/>
</bean>
<!-- Transaction manager for a single JPA EntityManagerFactory (alternative to JTA -->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<!-- enable the configuration of transactional behavior based on annotations -->
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
错误堆栈跟踪
由以下原因引起:org.springframework.beans.factory.BeanCreationException:创建类中定义了名称为"entityManagerFactory"的bean时出错路径资源[applicationContext securityEJB DBtest.xml]:bean类型[class的后期处理失败org.springframework.om.jpa.LocalContainerEntityManagerFactoryBean]失败;嵌套异常为java.lang.IollegalStateException:未能内省bean类[org.springframework.om.jpa.LocalContainerEntityManagerFactoryBean]对于持久性元数据:在中找不到它所依赖的类org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyMergedBeanDefinitionPostProcessors(AbstractAutowireCapableBeanFactory.java:936)在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:512)在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)在org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)在org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)在org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory:java:299)在org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)在org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:956)在org.springframework.context.support.AbstractApplicationContext.finishBeanFactory初始化(AbstractApplicationContext.java:747)在org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)在org.springframework.context.support.ClassPathXmlApplicationContext。(ClassPathXmlApplicationContext.java:139)在org.springframework.context.support.ClassPathXmlApplicationContext。(ClassPathXmlApplicationContext.java:93)位于的sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)在java.lang.reflect.Method.ioke(Method.java:606)org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)在org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)在org.junit.runners.model.FrameworkMethod.invokeExploly(FrameworkMethod.java:41)在org.junit.internal.runners.statements.InvokeMethod.eevaluate(InvokeMethod.java:20)在org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76)在org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)网址:org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)org.junit.runners.ParentRunner.runChildren(ParentRunner:191)org.junit.runners.ParentRunner.access$000(ParentRunner:42),网址:org.junit.runners.ParentRunner$2.eevaluate(ParentRunner.java:184)。。。11更多原因:java.lang.IollegalStateException:未能内省bean类[org.springframework.om.jpa.LocalContainerEntityManagerFactoryBean]对于持久性元数据:在中找不到它所依赖的类org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.findPersistenceMetadata(PersistenceAnnotatonBeanPostProcessor.java:396)在org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.postProcessMergedBeanDefinition(PersistenceAnnotatonBeanPostProcessor.java:333)在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyMergedBeanDefinitionPostProcessors(AbstractAutowireCapableBeanFactory.java:931)…44更多原因:java.lang.NoClassDefFoundError:位于的javax/persistence/ValidationMode位于的java.lang.Class.getDeclaredMethods0(本机方法)位于的java.lang.Class.privateGetDeclaredMethods(Class.java:2615)位于的java.lang.Class.getDeclaredMethods(Class.java:1860)org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.buildPersistenceMetadata(PersistenceAnnotatonBeanPostProcessor.java:420)在org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.findPersistenceMetadata(PersistenceAnnotatonBeanPostProcessor.java:392)…46更多原因:java.lang.ClassNotFoundException:位于的javax.persistence.ValidationModejava.net.URLClassLoader$1.run(URLClassLoader.java:366)java.net.URLClassLoader$1.run(URLClassLoader.java:355)位于的java.security.AccessController.doPrivileged(本机方法)java.net.URLClassLoader.findClass(URLClassLoader.java:354)java.lang.ClassLoader.loadClass(ClassLoader.java:425)sun.mic.Launcher$AppClassLoader.loadClass(Launcher.java:308)java.lang.ClassLoader.loadClass(ClassLoader.java:358)。。。再增加51个
项目中当前使用的技术 :Hibernate 3+和最近的技术堆栈升级Spring被更改为4.1版本。Spring 4.1强制使用JPA 2.0,同时它提供向后支持,这意味着它提供了JPA 1.0的支持,请参阅以下来自Spring网站的描述。
Java EE版本6或更高版本现在被认为是Spring的基线框架4,JPA 2.0和Servlet 3.0规范特别的相关性。为了与谷歌应用程序保持兼容引擎和较旧的应用程序服务器,可以部署Spring 4应用程序到Servlet 2.5环境中。然而,Servlet3.0+是强烈推荐的,也是Spring测试和模拟包中用于开发环境中测试设置的先决条件。
实际问题 :jUnit测试用例在以下突出显示的bean注入时间内失败。LocalContainerEntityManagerFactoryBean正在扩展Spring ORM类,它试图加载JPA 2.0特定的hibernate导入,但失败了。
<bean id="entityManagerFactory"
class="com.abc.persist.LocalContainerEntityManagerFactoryBean">
<property name="persistenceXmlLocation" value="classpath:META-INF/persistence-security.xml"/>
<property name="persistenceUnitName" value="casp-portal"/>
<property name="jpaPropertyMap">
<map>
<entry key="javax.persistence.sharedCache.mode" value="none" />
</map>
</property>
</bean>
<!-- Transaction manager for a single JPA EntityManagerFactory (alternative to JTA -->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<!-- enable the configuration of transactional behavior based on annotations -->
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
解决方案:
选项I:保留旧版本的Spring ORM,使其按原样工作[这是我们目前正在做的解决方案]。
选项II:将3,4个spring-orm java类复制到我们的项目中,并根据我们的需求调整spring-classes代码[我计划以这种方式实现]。
- 选项III:这是一项研究,试图找到另一种注入entityManager的替代方法