Spring JPA中@Autowired字段为Null的问题排查求助
解决Spring Data JPA @Autowired注入NullPointerException的问题
我来帮你排查这个NullPointerException问题,看了你的代码和配置,核心原因是Spring的注解驱动依赖注入没有生效,再加上对@Configuration注解的误用,导致CustomerRepository没有被正确注入到SpringJpaApp中。
问题根源分析
- 错误使用
@Configuration注解:你的SpringJpaApp类标注了@Configuration,但它本质是一个包含业务逻辑的组件,不是用来定义Spring配置的类。@Configuration应该用于声明Bean、配置Spring容器的类,而非普通业务类。 - 未开启注解驱动的依赖注入:你的XML配置里没有添加
<context:component-scan>或<context:annotation-config>,导致Spring无法识别并处理@Autowired、@Repository这类注解——虽然<jpa:repositories>已经扫描创建了CustomerRepository的代理Bean,但Spring不知道要把它注入到SpringJpaApp的字段中。 - 多余的
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
相关产品推荐
相关产品推荐

