简体   繁体   中英

org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean is failing after upgrading spring–orm jar to 4.1.6

Initially in our project we were using spring 3 + hibernate 3 Recently it has been decided to upgrade 3rd party jars, as part of that spring upgraded to 4 but not hibernate (still hibernate 3 is maintained). Now we have not changed any code for spring 4 upgrade and when we execute project LocalContainerEntityManagerFactoryBean injection is failing. I have given context file declaration & error stack trace in below. Now the question is how can I make existing project work on spring 4 with out upgrading hibernate.

With Spring ORM 4.1.6 LocalContainerEntityManagerFactoryBean is trying to load JPA 2.0 specific hibernate imports (that is hibernate 4 jar classes) and failing.

<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" />

Error Stack trace

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [applicationContext-securityEJB-DBtest.xml]: Post-processing failed of bean type [class org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean] failed; nested exception is java.lang.IllegalStateException: Failed to introspect bean class [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean] for persistence metadata: could not find class that it depends on at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyMergedBeanDefinitionPostProcessors(AbstractAutowireCapableBeanFactory.java:936) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:512) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194) at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:956) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:747) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480) at org.springframework.context.support.ClassPathXmlApplicationContext.(ClassPathXmlApplicationContext.java:139) at org.springframework.context.support.ClassPathXmlApplicationContext.(ClassPathXmlApplicationContext.java:93) 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.junit.runners.model.Framewor kMethod$1.runReflectiveCall(FrameworkMethod.java:44) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184) ... 11 more Caused by: java.lang.IllegalStateException: Failed to introspect bean class [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean] for persistence metadata: co uld not find class that it depends on at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.findPersistenceMetadata(PersistenceAnnotationBeanPostProcessor.java:396) at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.postProcessMergedBeanDefinition(PersistenceAnnotationBeanPostProcessor.java:333) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyMergedBeanDefinitionPostProcessors(AbstractAutowireCapableBeanFactory.java:931) ... 44 more Caused by: java.lang.NoClassDefFoundError: javax/persistence/ValidationMode at java.lang.Class.getDeclaredMethods0(Native Method) at java.lang.Class.privateGetDeclaredMethods(Class.java:2615) at java.lang.Class.getDeclaredMethods(Class.java:1860) at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.buildPersistenceMetadata(PersistenceAnnotationBeanPostProcessor.java:420) at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcesso r.findPersistenceMetadata(PersistenceAnnotationBeanPostProcessor.java:392) ... 46 more Caused by: java.lang.ClassNotFoundException: javax.persistence.ValidationMode at java.net.URLClassLoader$1.run(URLClassLoader.java:366) at java.net.URLClassLoader$1.run(URLClassLoader.java:355) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:354) at java.lang.ClassLoader.loadClass(ClassLoader.java:425) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308) at java.lang.ClassLoader.loadClass(ClassLoader.java:358) ... 51 more

Technologies used currently in project : Hibernate 3 + with recent tech stack upgrade Spring got changed to 4.1 version. Spring 4.1 is forces to use JPA 2.0, at the same time it does backward support, meaning it gives JPA 1.0 supports, see below description taken from Spring site.

Java EE version 6 or above is now considered the baseline for Spring Framework 4, with the JPA 2.0 and Servlet 3.0 specifications being of particular relevance. In order to remain compatible with Google App Engine and older application servers, it is possible to deploy a Spring 4 application into a Servlet 2.5 environment. However, Servlet 3.0+ is strongly recommended and a prerequisite in Spring's test and mock packages for test setups in development environments.

Actual Issue : jUnit test cases are failing during below highlighted bean injection time. LocalContainerEntityManagerFactoryBean which is extending Spring-ORM classes is trying to load JPA 2.0 specific hibernate imports and failing.

<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" />

Solutions :

  1. Option I : Keep the old version of Spring-ORM to make it work as is [This is what we currently doing as a work around].

  2. Option II : Copy 3,4 spring-orm java classes into our project and tweak the spring classes code according to our needs[I am planning to implement this way].

  3. Option III : This is in research, trying to find another alternative way to inject entityManager.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM