设置 Spring JPA 项目以在 MVC 项目中使用 - 创建 bean 时出错

Posted

技术标签:

【中文标题】设置 Spring JPA 项目以在 MVC 项目中使用 - 创建 bean 时出错【英文标题】:Setting up a Spring JPA project for use in an MVC project - Error creating bean 【发布时间】:2012-02-28 08:55:57 【问题描述】:

我在 Eclipse 中开发了一个 Spring JPA 项目,它可以访问存储在 mysql 服务器中的数据。现在我需要在 Spring@MVC 项目中导入这个项目。所以:

我在JPA项目的构建路径中配置导出maven依赖 我将项目添加到tomcat引导类路径中, 我将 JPA/Spring 项目添加到我的 Spring @MVC 项目的类路径中 我还将 jpa 应用程序上下文添加到 MVC 项目的根上下文中。

当我尝试在 tomcat 服务器上运行应用程序时出现错误。似乎我缺少 spring-beans 库,但正如您在 pom 配置中看到的那样,我导入了它。这是错误日志:

INFO: Initializing Spring root WebApplicationContext
INFO : org.springframework.web.context.ContextLoader - Root WebApplicationContext: initialization started
INFO : org.springframework.web.context.support.XmlWebApplicationContext - Refreshing Root WebApplicationContext: startup date [Mon Feb 06 22:26:12 CET 2012]; root of context hierarchy
INFO : org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from ServletContext resource [/WEB-INF/spring/root-context.xml]
INFO : org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from class path resource [META-INF/spring/app-context.xml]
INFO : org.springframework.context.annotation.ClassPathBeanDefinitionScanner - JSR-330 'javax.inject.Named' annotation found and supported for component scanning
INFO : org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor - JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
INFO : org.springframework.beans.factory.support.DefaultListableBeanFactory - Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@1d382926: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.annotation.internalPersistenceAnnotationProcessor,org.springframework.aop.config.internalAutoProxyCreator,org.springframework.transaction.interceptor.TransactionAttributeSourceAdvisor#0,org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor#0,org.springframework.transaction.interceptor.TransactionAttributeSourceAdvisor#1,org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor#0,entityManagerFactory,dataSource,transactionManager,jpaDaoRole,jpaDaoUser,homeController]; root of factory hierarchy
ERROR: org.springframework.web.context.ContextLoader - Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor#0' defined in class path resource [META-INF/spring/app-context.xml]: Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [META-INF/spring/app-context.xml]: Initialization of bean failed; nested exception is java.lang.NoSuchFieldError: NULL
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:527)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
    at org.springframework.context.support.AbstractApplicationContext.registerBeanPostProcessors(AbstractApplicationContext.java:710)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:410)
    at org.springframework.web.context.ContextLoader.createWebApplicationContext(ContextLoader.java:282)
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:204)
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:47)
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4206)
    at org.apache.catalina.core.StandardContext.start(StandardContext.java:4705)
    at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1057)
    at org.apache.catalina.core.StandardHost.start(StandardHost.java:840)
    at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1057)
    at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:463)
    at org.apache.catalina.core.StandardService.start(StandardService.java:525)
    at org.apache.catalina.core.StandardServer.start(StandardServer.java:754)
    at org.apache.catalina.startup.Catalina.start(Catalina.java:595)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:289)
    at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:414)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [META-INF/spring/app-context.xml]: Initialization of bean failed; nested exception is java.lang.NoSuchFieldError: NULL
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:527)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeansOfType(DefaultListableBeanFactory.java:400)
    at org.springframework.beans.factory.BeanFactoryUtils.beansOfTypeIncludingAncestors(BeanFactoryUtils.java:275)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.detectPersistenceExceptionTranslators(PersistenceExceptionTranslationInterceptor.java:122)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.<init>(PersistenceExceptionTranslationInterceptor.java:78)
    at org.springframework.dao.annotation.PersistenceExceptionTranslationAdvisor.<init>(PersistenceExceptionTranslationAdvisor.java:70)
    at org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor.setBeanFactory(PersistenceExceptionTranslationPostProcessor.java:96)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeAwareMethods(AbstractAutowireCapableBeanFactory.java:1475)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1443)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
    ... 25 more
Caused by: java.lang.NoSuchFieldError: NULL
    at org.springframework.expression.TypedValue.<clinit>(TypedValue.java:32)
    at org.springframework.expression.spel.support.StandardEvaluationContext.setRootObject(StandardEvaluationContext.java:85)
    at org.springframework.expression.spel.support.StandardEvaluationContext.<init>(StandardEvaluationContext.java:74)
    at org.springframework.context.expression.StandardBeanExpressionResolver.evaluate(StandardBeanExpressionResolver.java:124)
    at org.springframework.beans.factory.support.AbstractBeanFactory.evaluateBeanDefinitionString(AbstractBeanFactory.java:1299)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.evaluate(BeanDefinitionValueResolver.java:224)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:311)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:106)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1360)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1118)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517)
    ... 39 more

这是我的应用上下文:

<dependencies>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-entitymanager</artifactId>
        <version>3.6.0.Final</version>
    </dependency>
    <dependency>
        <groupId>javax.validation</groupId>
        <artifactId>validation-api</artifactId>
        <version>1.0.0.GA</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-validator</artifactId>
        <version>4.1.0.Final</version>
    </dependency>

    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.7</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-test</artifactId>
        <version>$spring.framework.version</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
        <version>$spring.framework.version</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aop</artifactId>
        <version>$spring.framework.version</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-orm</artifactId>
        <version>$spring.framework.version</version>
    </dependency>
    <dependency>
        <groupId>commons-dbcp</groupId>
        <artifactId>commons-dbcp</artifactId>
        <version>1.2.2</version>
    </dependency>       
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.16</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
        <version>1.6.4</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.18</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aspects</artifactId>
        <version>3.1.0.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.6.4</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>3.1.0.RELEASE</version>
    </dependency>
</dependencies>

这是我的 jpa 项目的应用上下文:

<?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:context="http://www.springframework.org/schema/context"
    xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <description>Example configuration to get you started.</description>
    
    <!-- Generic -->
    <context:annotation-config />
    <tx:annotation-driven transaction-manager="transactionManager" />
 
    <!-- JPA -->
    
    <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
    <tx:annotation-driven />
    <bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/> 
    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                <property name="showSql" value="true" /> <!-- Prints used SQL to stdout -->
                <property name="generateDdl" value="true" /> <!-- Generates tables. -->
                <property name="databasePlatform" value="org.hibernate.dialect.MySQL5Dialect" />
            </bean>
        </property>
    </bean>
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/windydb"/>
        <property name="username" value="windyuser"/>
        <property name="password" value="maverick1984"/>
    </bean>
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory"/>
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <context:component-scan base-package="com.windy.spring" />

</beans>

【问题讨论】:

在您的 POM(第二部分)中,属性 $spring.framework.version 的值是多少? 【参考方案1】:

在我的情况下,冲突是由仍在使用旧版本的 spring security 引起的。 我在上面放了一些排除项,现在可以了。 将这些东西放在dependencyManagement中可能也是一件好事,这样您就不必在每个模块中重复。

我正在使用以下内容:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>$spring.framework.version</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>$spring.framework.version</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>$spring.framework.version</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-core</artifactId>
            <version>$spring.security.framework.version</version>

            <exclusions>
                <exclusion>
                    <groupId>org.springframework</groupId>
                    <artifactId>spring-aop</artifactId>
                </exclusion>

                <exclusion>
                    <groupId>org.springframework</groupId>
                    <artifactId>spring-expression</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-config</artifactId>
            <version>$spring.security.framework.version</version>

            <exclusions>
                <exclusion>
                    <groupId>org.springframework</groupId>
                    <artifactId>spring-aop</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-web</artifactId>
            <version>$spring.security.framework.version</version>
            <exclusions>
                <exclusion>
                     <groupId>org.springframework</groupId>
                    <artifactId>spring-tx</artifactId>
                </exclusion>

                <exclusion>
                    <groupId>org.springframework</groupId>
                    <artifactId>spring-jdbc</artifactId>
                </exclusion>

                <exclusion>
                    <groupId>org.springframework</groupId>
                    <artifactId>spring-aop</artifactId>
                </exclusion>

                <exclusion>
                    <groupId>org.springframework</groupId>
                    <artifactId>spring-expression</artifactId>
                </exclusion>
            </exclusions>
        </dependency>


        <dependency>
            <groupId>org.hibernate.javax.persistence</groupId>
            <artifactId>hibernate-jpa-2.0-api</artifactId>
            <version>1.0.1.Final</version>
        </dependency>

        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>4.0.1.Final</version>
        </dependency>
    </dependencies>
</dependencyManagement>

没有排除项,我遇到了与该线程开头所述相同的错误。 我用于 spring 的版本是:

<properties>
    <spring.framework.version>3.1.1.RELEASE</spring.framework.version>
    <spring.security.framework.version>3.1.0.RELEASE</spring.security.framework.version>
</properties>

【讨论】:

【参考方案2】:

我也遇到了同样的问题,结果确实是版本不匹配,我的问题是我使用了一个服务器变量,形式为 $server.env,正是这个给了问题。因为我的 spring-expression 版本仍然是 3.0.5。您应该尝试将这些添加到您的 pom 中:

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-expression</artifactId>
            <version>$version.spring.framework</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>$version.spring.framework</version>
        </dependency>           

【讨论】:

【参考方案3】:

这确实通常是由某处的版本不匹配引起的。验证所有 spring jars 版本。如果它仍然不起作用,也许升级您的 JPA 提供程序。

【讨论】:

【参考方案4】:

依赖关系:

   <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aspects</artifactId>
    <version>3.1.0.RELEASE</version>
   </dependency>

   <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>3.1.0.RELEASE</version>
   </dependency>

这些 (3.1.0.RELEASE) 的版本是否与 maven 变量 $spring.framework.version 匹配。据我所知,这可能会导致版本不匹配,并且可能会导致 no such field 错误,这通常是由版本不匹配引起的。

【讨论】:

以上是关于设置 Spring JPA 项目以在 MVC 项目中使用 - 创建 bean 时出错的主要内容,如果未能解决你的问题,请参考以下文章

如何操纵我的审计项目以在 Spring Boot 中持续存在

使用 spring-data-jpa 和 spring-mvc 过滤数据库行

Gradle 如何配置构建文件以从同一项目创建 Spring boot jar 和 spring web-mvc war

如何在 spring roo 项目中安装 JPA 持久性提供程序?

最近项目中使用Spring data jpa 踩过的坑

SpringBoot中使用Spring Data JPA