org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean 升级 spring–orm jar 到 4.1.6 后失败

Posted

技术标签:

【中文标题】org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean 升级 spring–orm jar 到 4.1.6 后失败【英文标题】:org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean is failing after upgrading spring–orm jar to 4.1.6 【发布时间】:2016-07-25 14:29:34 【问题描述】:

最初在我们的项目中,我们使用的是 spring 3 + hibernate 3 最近决定升级 3rd 方 jars,作为 spring 升级到 4 但不是 hibernate 的一部分(仍然保持 hibernate 3)。 现在我们没有为 spring 4 升级更改任何代码,当我们执行项目时 LocalContainerEntityManagerFactoryBean 注入失败。我在下面给出了上下文文件声明和错误堆栈跟踪。现在的问题是如何在不升级hibernate的情况下让现有项目在spring 4上运行。

使用 Spring ORM 4.1.6 LocalContainerEntityManagerFactoryBean 正在尝试加载 JPA 2.0 特定的休眠导入(即休眠 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.orm.jpa.LocalContainerEntityManagerFactoryBean] 失败的;嵌套异常是 java.lang.IllegalStateException: Failed to 内省 bean 类 [org.springframework.orm.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.finishBeanFactoryInitialization(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(Native Method) 在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 在 java.lang.reflect.Method.invoke(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.invokeExplosively(FrameworkMethod.java:41) 在 org.junit.internal.runners.statements.InvokeMethod.evaluate(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.java:191) 在 org.junit.runners.ParentRunner.access$000(ParentRunner.java:42) 在 org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184) ... 11 更多原因:java.lang.IllegalStateException: Failed to 内省 bean 类 [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean] 对于持久性元数据:找不到它所依赖的类 org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.findPersistenceMetadata(PersistenceAnnotationBeanPostProcessor.java:396) 在 org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.postProcessMergedBeanDefinition(PersistenceAnnotationBeanPostProcessor.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(PersistenceAnnotationBeanPostProcessor.java:420) 在 org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.findPersistenceMetadata(PersistenceAnnotationBeanPostProcessor.java:392) ... 46 更多原因:java.lang.ClassNotFoundException: javax.persistence.ValidationMode 在 java.net.URLClassLoader$1.run(URLClassLoader.java:366) 在 java.net.URLClassLoader$1.run(URLClassLoader.java:355) 在 java.security.AccessController.doPrivileged(Native Method) 在 java.net.URLClassLoader.findClass(URLClassLoader.java:354) 在 java.lang.ClassLoader.loadClass(ClassLoader.java:425) 在 sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308) 在 java.lang.ClassLoader.loadClass(ClassLoader.java:358) ... 51 更多

【问题讨论】:

【参考方案1】:

项目中当前使用的技术: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 规范 特别相关。为了与 Google App 保持兼容 引擎和较旧的应用程序服务器,可以部署一个 Spring 4 应用程序转换为 Servlet 2.5 环境。然而,Servlet 强烈建议使用 3.0+,并且是 Spring 的测试和模拟包的先决条件,用于在开发环境中进行测试设置。

实际问题:jUnit 测试用例在以下突出显示的 bean 注入时间内失败。扩展 Spring-ORM 类的 LocalContainerEntityManagerFactoryBean 正在尝试加载 JPA 2.0 特定的休眠导入并失败。

<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 以使其按原样工作 [这是我们目前正在做的解决方法]。

    选项二:将 3,4 个 spring-orm java 类复制到我们的项目中,并根据我们的需要调整 spring 类代码[我打算这样实现]。

    方案三:这是在研究中,试图找到另一种注入 entityManager 的替代方法。

【讨论】:

以上是关于org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean 升级 spring–orm jar 到 4.1.6 后失败的主要内容,如果未能解决你的问题,请参考以下文章