You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring JPA中@Autowired字段为Null的问题排查求助

解决Spring Data JPA @Autowired注入NullPointerException的问题

我来帮你排查这个NullPointerException问题,看了你的代码和配置,核心原因是Spring的注解驱动依赖注入没有生效,再加上对@Configuration注解的误用,导致CustomerRepository没有被正确注入到SpringJpaApp中。

问题根源分析

  1. 错误使用@Configuration注解:你的SpringJpaApp类标注了@Configuration,但它本质是一个包含业务逻辑的组件,不是用来定义Spring配置的类。@Configuration应该用于声明Bean、配置Spring容器的类,而非普通业务类。
  2. 未开启注解驱动的依赖注入:你的XML配置里没有添加<context:component-scan>或<context:annotation-config>,导致Spring无法识别并处理@Autowired、@Repository这类注解——虽然<jpa:repositories>已经扫描创建了CustomerRepository的代理Bean,但Spring不知道要把它注入到SpringJpaApp的字段中。
  3. 多余的refresh()调用:ClassPathXmlApplicationContext在初始化时已经自动执行了refresh(),手动再次调用不仅多余,还可能导致容器状态异常。

分步解决方案

1. 修改SpringJpaApp类

把它改成普通业务组件,去掉@Configuration,添加@Component让Spring能扫描到它:

@Component
public class SpringJpaApp {
    @Autowired
    CustomerRepository customerRepository;

    public static void main(String[] args) {
        ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        try {
            // 直接通过类型获取Bean,更简洁
            SpringJpaApp s = ctx.getBean(SpringJpaApp.class);
            s.process();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 记得关闭容器,释放资源
            ctx.close();
        }
    }

    public String process() {
        // save a single Customer
        customerRepository.save(new Customer("Jack", "Smith"));
        // save a list of Customers
        customerRepository
                .save(Arrays.asList(new Customer("Adam", "Johnson"), new Customer("Kim", "Smith"), new Customer("David", "Williams"), new Customer("Peter", "Davis")));
        return "Done";
    }
}

2. 更新XML配置文件

添加组件扫描,移除手动注册的mainBean(组件扫描会自动发现SpringJpaApp):

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

    <!-- 开启组件扫描,Spring会自动处理注解驱动的Bean和依赖注入 -->
    <context:component-scan base-package="com.springjpa"/>

    <jpa:repositories base-package="com.springjpa.repo" />

    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="location">
            <value>application.properties</value>
        </property>
    </bean>

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="url" value="${spring.datasource.url}"/>
        <property name="username" value="${spring.datasource.username}"/>
        <property name="password" value="${spring.datasource.password}"/>
    </bean>

    <bean class="org.springframework.orm.jpa.JpaTransactionManager" id="transactionManager">
        <property name="dataSource" ref="dataSource" />
        <property name="entityManagerFactory" ref="entityManagerFactory" />
    </bean>

    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="packagesToScan" value="com.springjpa" />
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
        </property>
        <property name="jpaProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQL9Dialect</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.hbm2ddl.auto">update</prop>
            </props>
        </property>
    </bean>

    <!-- 移除手动注册的mainBean,由component-scan自动发现 -->
    <!-- <bean id="mainBean" class="com.springjpa.controller.SpringJpaApp"/> -->
</beans>

3. 关于Hibernate警告的额外说明

你堆栈里的无法使用Java 1.7 Connection#getSchema警告,是因为你用的PostgreSQL JDBC驱动版本太旧(9.1),不支持Java 7的getSchema()方法。这个警告不影响功能,但如果想消除它,可以把JDBC驱动升级到42.x系列的新版本。

内容的提问来源于stack exchange,提问作者Gayane Dzvakeryan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 09:08:08