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

Spring Boot中ItemRepository注入为null报错原因及修复方法

问题场景

Service层代码

package com.example.demo.service;
import com.example.demo.dto.Invoicedto;
import com.example.demo.model.Item;
import com.example.demo.repository.ItemRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;

@Service
public class InvoiceService implements InvoiceServiceInterface {
    @Autowired
    private ItemRepository itemRepository;
    public void createInvoice(Invoicedto invoiceDto) {
        try {
            List<Item> itemList = this.itemRepository.findAll();
            for (Item item : itemList) {
                System.out.println(item.getId());
            }
        } catch (Exception e) {
            System.out.println("Exception occurred " + e.getMessage());
        }
    }
}

Repository层代码

package com.example.demo.repository;
import com.example.demo.model.Item;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;

@Repository
public interface ItemRepository   extends JpaRepository<Item, Long> {

    List<Item> findAll();

    @Modifying
    @Query("DELETE Item c WHERE c.id = ?1")
    void deleteById(long id); 
}

运行时抛出异常:

Exception occurred Cannot invoke "com.example.demo.repository.ItemRepository.findAll()" because "this.itemRepository" is null


根本原因

this.itemRepository为null的核心原因是当前执行方法的InvoiceService实例并非Spring IoC容器管理的Bean,未完成依赖注入流程,绝大多数场景是手动通过new InvoiceService()创建实例使用,这种实例不会被Spring处理@Autowired注入逻辑,成员变量保持默认null值。
其他可能的触发场景:

  • Spring启动类包扫描范围未覆盖com.example.demo.repository包,ItemRepository未被注册为容器Bean,导致注入失败
  • 在InvoiceService的构造函数内部直接调用createInvoice业务方法,此时构造阶段尚未完成依赖注入,属性仍为null
  • 额外注意:Repository中自定义的删除方法未加事务注解、手动重写JpaRepository自带的findAll方法属于不规范写法,会引发后续的事务、代理相关异常,但不是本次空指针的直接诱因。
修复方案
  • 所有用到InvoiceService的位置(如Controller、其他业务组件)禁止手动new实例,统一通过@Autowired注入Spring管理的InvoiceServiceBean使用
  • 检查启动类位置:Spring Boot启动类建议放在com.example.demo根包下,默认会扫描所有子包的组件;如果启动类位置不在根包,手动添加注解明确扫描范围:
    @SpringBootApplication(scanBasePackages = "com.example.demo")
    @EnableJpaRepositories(basePackages = "com.example.demo.repository")
    @EntityScan(basePackages = "com.example.demo.model")
    public class DemoApplication {
        public static void main(String[] args) {
            SpringApplication.run(DemoApplication.class, args);
        }
    }
    
  • 不要在构造函数中执行业务逻辑,如果需要服务启动后初始化执行逻辑,使用@PostConstruct注解标记初始化方法,保证依赖注入完成后再执行
  • 清理Repository层冗余代码:删除手动声明的List<Item> findAll();(JpaRepository已经提供该方法默认实现,手动重写会干扰JPA代理生成),给自定义删除方法补上@Transactional注解:
    @Repository
    public interface ItemRepository extends JpaRepository<Item, Long> {
        @Modifying
        @Transactional
        @Query("DELETE Item c WHERE c.id = ?1")
        void deleteById(long id); 
    }
    
  • 推荐使用构造函数注入替代字段注入,既能保证依赖不可变,也能在启动阶段就暴露注入失败的问题,避免运行时空指针:
    @Service
    public class InvoiceService implements InvoiceServiceInterface {
        private final ItemRepository itemRepository;
    
        public InvoiceService(ItemRepository itemRepository) {
            this.itemRepository = itemRepository;
        }
    
        public void createInvoice(Invoicedto invoiceDto) {
            List<Item> itemList = this.itemRepository.findAll();
            for (Item item : itemList) {
                System.out.println(item.getId());
            }
        }
    }
    

内容的提问来源于stack exchange,提问作者Nipuna Chandimal

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 09:45:37