添加@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
相关产品推荐
相关产品推荐

