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

SpringBoot调用Repository的@Query方法获取查询结果时报空指针异常

问题排查与解决方案

核心原因分析

  • 你代码中用到的@PrePersist、@PreUpdate属于JPA实体生命周期回调注解,这类回调对应的实例默认由Hibernate等JPA实现直接创建,不受Spring容器管理,因此类内标注的@Autowired不会生效,你拿到的demoRepository本身就是空对象,调用方法时就会出现异常或者返回null。
  • 次要排查点:当数据库中DemoStudentData表没有数据时,SUM聚合函数的返回值本身就是null,这属于SQL的正常行为,如果是首次插入数据的场景,@PrePersist执行时新数据还未落库,也会触发该情况。

对应解决方案

方案1:开启实体监听器的Spring注入能力

如果你是将SampleMarksValues作为实体监听器使用(即DemoStudentData类上标注了@EntityListeners(SampleMarksValues.class)),可以通过Spring的AspectJ织入能力实现非Spring管理实例的依赖注入:

  1. 给SampleMarksValues类添加@Configurable注解
  2. 项目引入AOP依赖,Spring Boot项目直接添加spring-boot-starter-aop即可
  3. 在项目配置类上添加@EnableSpringConfigured注解,开启注入支持

方案2:手动从Spring上下文获取Repository实例

不需要修改AOP配置,通过工具类主动获取Bean,兼容性更强:

  1. 新增Spring上下文工具类:
@Component
public class SpringContextHolder implements ApplicationContextAware {
    private static ApplicationContext context;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        context = applicationContext;
    }

    public static <T> T getBean(Class<T> beanClass) {
        return context.getBean(beanClass);
    }
}
  1. 修改回调方法的逻辑,手动获取Repository实例:
@PreUpdate
@PrePersist
public void useTotalMarks(DemoStudentData demo) {
    DemoRepository repo = SpringContextHolder.getBean(DemoRepository.class);
    Double marks = repo.totalMarks();
    demo.setTotal_Marks(marks);
}

额外优化:避免SUM返回null

修改Repository层的查询语句,用COALESCE函数处理空值,无数据时默认返回0:

@Query("SELECT COALESCE(SUM(dt.demo_marks), 0) FROM DemoStudentData dt")
Double totalMarks();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 21:15:02