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

添加@DeleteMapping至Spring Boot Rest服务引发依赖与空指针异常

问题:Spring Boot添加@DeleteMapping后编译报错

错误堆栈

java.lang.IllegalStateException: Failed to load ApplicationContext
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'eligibleAddOnController': Unsatisfied dependency expressed through field 'eligibilityRepository'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'eligibilityRepository' defined in pack.psl.repository.EligibilityRepository defined in @EnableJpaRepositories declared on JpaRepositoriesRegistrar.EnableJpaRepositoriesConfiguration: Invocation of init method failed; nested exception is org.springframework.data.repository.query.QueryCreationException: Could not create query for public abstract void pack.psl.repository.EligibilityRepository.deleteAddOn(java.lang.String,java.lang.String); Reason: null; nested exception is java.lang.NullPointerException
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'eligibilityRepository' defined in nz.one.psl.repository.EligibilityRepository defined in @EnableJpaRepositories declared on JpaRepositoriesRegistrar.EnableJpaRepositoriesConfiguration: Invocation of init method failed; nested exception is org.springframework.data.repository.query.QueryCreationException: Could not create query for public abstract void pack.psl.repository.EligibilityRepository.deleteAddOn(java.lang.String,java.lang.String); Reason: null; nested exception is java.lang.NullPointerException
Caused by: org.springframework.data.repository.query.QueryCreationException: Could not create query for public abstract void pack.psl.repository.EligibilityRepository.deleteAddOn(java.lang.String,java.lang.String); Reason: null; nested exception is java.lang.NullPointerException
Caused by: java.lang.NullPointerException

相关代码

Application类

package pack.psl;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class TcsApplication {

    public static void main(String[] args) {
        SpringApplication.run(TcsApplication.class, args);
    }

}

Model类

package pack.model;

import javax.persistence.*;
import javax.validation.constraints.*;

@Entity
@Table(name = "DEALS")
public class EligibleAddOn {
    
    @Id
    @NotNull
    private String deals_id;
    @NotNull
    private String cust_id;
    @NotNull
    private String addon_name;
    @NotNull
    private String eligibility_from_date;
    @NotNull
    private String eligibility_to_date;

    public EligibleAddOn() {
        super();
    }

    public String getDeals_id() {
        return deals_id;
    }

    public void setDeals_id(String deals_id) {
        this.deals_id = deals_id;
    }

    public String getCust_id() {
        return cust_id;
    }

    public void setCust_id(String cust_id) {
        this.cust_id = cust_id;
    }

    public String getAddon_Name() {
        return addon_name;
    }

    public void setAddon_Name(String addon_Name) {
        this.addon_name = addon_Name;
    }

    public String getEligibility_from_date() {
        return eligibility_from_date;
    }

    public void setEligibility_from_date(String eligibility_from_date) {
        this.eligibility_from_date = eligibility_from_date;
    }

    public String getEligibility_to_date() {
        return eligibility_to_date;
    }

    public void setEligibility_to_date(String eligibility_to_date) {
        this.eligibility_to_date = eligibility_to_date;
    }

}

Repository接口

package pack.repository;


import java.util.List;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.transaction.annotation.Transactional;

import pack.model.EligibleAddOn;

public interface EligibilityRepository extends JpaRepository<EligibleAddOn, String> {
    @Transactional
    @Query(value = "select * from DEALS "
            + "where CUST_ID IN "
            + "(select CUST_ID from TCS_CUSTOMER where msisdn = ?) "
            + "and ELIGIBILITY_FROM_DATE < current_timestamp "
            + "and current_timestamp < ELIGIBILITY_TO_DATE "
            + "ORDER BY DISPLAY_PRIORITY", nativeQuery = true)
    List<EligibleAddOn> findByMsisdn(String msisdn);

    @Modifying
    @Transactional
    @Query(value = "delete from DEALS where " +
    "CUST_ID in (select CUST_ID from TCS_CUSTOMER " +
    "where MSISDN = :msisdn) and addon_name" + " = :addon_name", nativeQuery 
    =true) void deleteAddOn(@Param("msisdn")String
    msisdn, @Param("addon_name")String addon_name);


}

Controller类

package pack.controller;

import pack.exception.EligibleAddOnNotFoundException;
import pack.model.EligibleAddOn;
import pack.repository.EligibilityRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import javax.validation.Valid;
import java.util.List;

@RestController
@RequestMapping("/tcs")
public class EligibleAddOnController {

    @Autowired
    EligibilityRepository eligibilityRepository;


// 获取单个套餐

    @GetMapping("/eligibility-list/msisdn/{msisdn}")
    public List<EligibleAddOn> getEligibleAddOnByMsisdn(@PathVariable(value = "msisdn") String msisdn)
            throws EligibleAddOnNotFoundException {
        return eligibilityRepository.findByMsisdn(msisdn);

    }

// 删除套餐
@DeleteMapping("/eligibility-list/msisdn/{msisdn}/radon/{addon_name}") public
     ResponseEntity<?> deleteEligibleAddOn(@PathVariable("msisdn") String
     msisdn,@PathVariable("addon_name") String addon_name){
     
     eligibilityRepository.deleteAddOn(msisdn, addon_name);
     
     return ResponseEntity.ok().build(); }
     
}

Application.properties配置

spring.jpa.hibernate.ddl-auto=none
spring.datasource.url= datasource
spring.datasource.username= username
spring.datasource.password= password
spring.datasource.driver-class-name=oracle.jdbc.OracleDriver
spring.jpa.database-platform=org.hibernate.dialect.Oracle12cDialect
server.error.include-stacktrace = always

解决方案

1. 修复Repository中deleteAddOn方法的SQL语句和格式

原代码中SQL字符串拼接的换行、空格问题,以及Oracle字段名大小写不匹配,是触发空指针的核心原因。修改后的代码如下:

@Modifying
@Transactional
@Query(value = "delete from DEALS where CUST_ID in (select CUST_ID from TCS_CUSTOMER where MSISDN = :msisdn) and ADDON_NAME = :addon_name", nativeQuery = true)
void deleteAddOn(@Param("msisdn") String msisdn, @Param("addon_name") String addon_name);

修改点说明:

  • 将分散拼接的SQL整合成完整语句,避免解析时的格式错误
  • 把addon_name改为大写ADDON_NAME,匹配Oracle数据库默认的大写字段名
  • 规整方法定义的换行,确保Spring能正确解析方法签名

2. 修复Model类的JavaBean规范问题(可选但推荐)

Model类中addon_name字段的getter/setter命名不符合JavaBean规范,改为驼峰命名:

public String getAddonName() {
    return addon_name;
}

public void setAddonName(String addonName) {
    this.addon_name = addonName;
}

3. 验证基础配置

确保spring-boot-starter-data-jpa依赖已正确引入,数据库连接配置无误,编译时能正常访问数据库元数据(若开启相关校验)。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 08:42:44