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

Spring Boot中如何通过实体属性校验实现条件删除?

问题与解决方案

问题描述

需要在执行deleteById()删除操作前,校验数据库中status列的值:仅当值为0或2时允许删除,值为1则禁止删除。业务逻辑放在Service层,但启动应用时出现依赖注入错误,提示找不到ReportRequest类型的Bean。

错误信息

Error starting ApplicationContext. To display the conditions report re-run your 
application with 'debug' enabled.
2022-10-25 18:44:38.538 ERROR 2328 --- [           main] 
o.s.b.d.LoggingFailureAnalysisReporter   : 

***************************
APPLICATION FAILED TO START
***************************

Description:

Parameter 0 of constructor in com.ssc.test.cb3.service.ReportRequestService required a 
bean of type 'com.ssc.test.cb3.model.ReportRequest' that could not be found.

The injection point has the following annotations:
- @org.springframework.beans.factory.annotation.Autowired(required=true)


Action:

Consider defining a bean of type 'com.ssc.test.cb3.model.ReportRequest' in your 
configuration.

2022-10-25 18:44:38.543 ERROR 2328 --- [           main] 
o.s.test.context.TestContextManager      : Caught exception while allowing 
TestExecutionListener 
[org.springframework.test.context.web.ServletTestExecutionListener@7d446ed1] to prepare 
test instance [com.ssc.test.cb3.Cb3ApplicationTests@1f72fbd1]

java.lang.IllegalStateException: Failed to load ApplicationContext

 Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 4.735 s <<< FAILURE! - 
in com.ssc.test.cb3.Cb3ApplicationTests
contextLoads  Time elapsed: 0.001 s  <<< ERROR!
java.lang.IllegalStateException: Failed to load ApplicationContext
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error 
creating bean with name 'reportRequestController': Unsatisfied dependency expressed 
through field 'reportRequestService'; nested exception is 
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean 
with name 'reportRequestService' defined in file

错误末尾信息:

No qualifying bean of type 'com.ssc.test.cb3.model.ReportRequest' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}

相关代码

模型类ReportRequest

package com.ssc.test.cb3.model;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * Class that models the entity report request table of the database
 * @author ssc
 */
@Entity
@Table(name = "report_request")
@Data
public class ReportRequest {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "seq_id")
    private int id;

    @Column(name = "request_date", insertable = false, nullable = true)
    private String requestDate;

    @Column(name = "request_userid")
    private int requestUserId;

    @Column(name = "request_email")
    private String requestEmail;

    @Column(name = "start_date")
    private String startDate;

    @Column(name = "end_date")
    private String endDate;

    @Column(name = "report_type")  
    private int reportType; // 0 === cliente, 1 === proveedor

    @Column(name = "contact_id")
    private int contactId;

    @Column(name = "contact_id_customer")  // Id from the client or provider chosen
    private int contactIdCustomer;

    @Column(name = "contact_id_provider")  // Id from the provider or provider chosen
    private int contactIdProvider;

    private String rgids;

    private int status;   // 0 === active, 1 === inactive

    @Column(name = "process_start")
    private String processStart;

    @Column(name = "process_finish")
    private String processFinish;

    @Column(name = "call_filter")  // 0 === Answered calls, 1 === Not answered, 2 === both
    private int callQuery;

    @Column(name = "file_name")
    private String fileName;

}

Repository类

package com.ssc.test.cb3.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import com.ssc.test.cb3.model.ReportRequest;

/**
 * Class that extends to the repository for database management queries with
 * table report_request
 *
 * @author ssc
 */
@Repository
public interface ReportRequestRepository extends JpaRepository<ReportRequest, Integer> {

    
}

Service类(错误版本)

package com.ssc.test.cb3.service;

import com.ssc.test.cb3.repository.ReportRequestRepository;
import org.springframework.stereotype.Service;
import com.ssc.test.cb3.model.ReportRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;


/**
 * Class to prepare the services to be dispatched upon request.
 *
 * @author ssc
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class ReportRequestService {

    @Autowired
    private ReportRequest reportRequest;
    
    private final ReportRequestRepository reportRequestRepository;

    /**
     * Function to delete a report from the database
     *
     * @param id from the report request objet to identify what is the specific
     * report
     */
//    public void delete(int id) {
//        log.info("The report request {} was successfully deleted", id);
//        reportRequestRepository.deleteById(id);
//    }

    public void delete(int id) {
        if (reportRequest.getStatus() != 1) {
            log.info("The report request {} was successfully deleted", id);
            reportRequestRepository.deleteById(id);
        } else {
            log.error("It was not possible to delete the selected report as it hasn't been processed yet");
        }
    }

}

Controller类

package com.ssc.test.cb3.controller;

import com.ssc.test.cb3.model.ReportRequest;
import com.ssc.test.cb3.service.ReportRequestService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * Class to handle REST services and APIs for the download Report's class
 *
 * @author ssc
 */
@RestController
@RequestMapping("/v1/reportRequest")
@CrossOrigin(origins = "http://localhost:3000")
public class ReportRequestController {


    @Autowired
    private ReportRequestService reportRequestService;

    /**
     * Method to delete a report request by its id number, it will call the service method and passed the id captured
     * @param id 
     */
    @DeleteMapping("/delete/{id}")
    public void deleteReport(@PathVariable int id) {
        reportRequestService.delete(id);
    }

}

解决方案

1. 修复依赖注入错误

错误根源是Service中尝试注入ReportRequest实体类,但ReportRequest是JPA实体,不是Spring管理的Bean(没有@Component等Spring注解),无法通过@Autowired注入。直接删除这行代码:

@Autowired
private ReportRequest reportRequest;

2. 修正删除逻辑

要校验指定id的实体状态,需先通过Repository从数据库中查询该实体,再判断status值:

@Service
@RequiredArgsConstructor
@Slf4j
public class ReportRequestService {

    private final ReportRequestRepository reportRequestRepository;

    public void delete(int id) {
        // 通过id查询实体,若不存在则抛出异常或处理
        ReportRequest reportRequest = reportRequestRepository.findById(id)
                .orElseThrow(() -> new IllegalArgumentException("Report request with id " + id + " not found"));
        
        // 校验status:0或2允许删除,1禁止
        if (reportRequest.getStatus() != 1) {
            reportRequestRepository.deleteById(id);
            log.info("The report request {} was successfully deleted", id);
        } else {
            log.error("Cannot delete report request {}: status is 1 (unprocessed)", id);
            // 可抛出自定义异常,让Controller返回对应HTTP状态码
            throw new IllegalStateException("Cannot delete unprocessed report request");
        }
    }
}

3. 优化Controller返回结果

为了让前端感知删除结果,修改Controller方法返回ResponseEntity:

@DeleteMapping("/delete/{id}")
public ResponseEntity<String> deleteReport(@PathVariable int id) {
    try {
        reportRequestService.delete(id);
        return ResponseEntity.ok("Report request deleted successfully");
    } catch (IllegalArgumentException e) {
        return ResponseEntity.status(HttpStatus.NOT_FOUND).body(e.getMessage());
    } catch (IllegalStateException e) {
        return ResponseEntity.status(HttpStatus.FORBIDDEN).body(e.getMessage());
    }
}

这样既解决了依赖注入错误,又实现了删除前的状态校验逻辑,同时给前端返回明确的响应结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 11:45:36