Spring Boot内存Map实现CRUD接口返回200但无数据求助
问题排查请求
Spring Boot应用能正常启动,也能保存记录,但通过REST Controller执行CRUD操作时,从内存Map获取记录会返回200 OK响应却无数据内容,不过/hello接口可正常返回"Hello World"。确认Controller类的对象注入无问题,恳请提供排查思路,相关代码如下:
主应用类
@ComponentScan("com.someone.organization") @SpringBootApplication public class WorkingOrganizationApplication { public static void main(String[] args) { SpringApplication.run(WorkingOrganizationApplication.class, args); @SuppressWarnings("resource") AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); context.scan("com.someone.organization"); context.refresh(); EmployeeRepository empRepository = context.getBean(EmployeeRepository.class); //testing the store method empRepository.save(new Employee(1L, "XYZ","PQR")); empRepository.save(new Employee(2L, "ABC","PQR")); empRepository.save(new Employee(3L, "MNC","PQR")); Employee employee = empRepository.findById(1L); System.out.println(employee.toString()); Employee employee2 = empRepository.findById(2L); System.out.println(employee2.toString()); // close the spring context context.close(); } }
Entity类
public class Employee { private Long Employee_Id; @Override public String toString() { return "Employee{" + "Employee_Id=" + Employee_Id + ", Employee_first_name='" + Employee_first_name + '\'' + ", Employee_last_name='" + Employee_last_name + '\'' + '}'; } private String Employee_first_name; private String Employee_last_name; public Long getEmployeeId() { return Employee_Id; } public void setEmployee_Id(Long employee_Id) { Employee_Id = employee_Id; } public String getEmployee_first_name() { return Employee_first_name; } public void setEmployee_first_name(String employee_first_name) { Employee_first_name = employee_first_name; } public String getEmployee_last_name() { return Employee_last_name; } public void setEmployee_last_name(String employee_last_name) { Employee_last_name = employee_last_name; } public Employee(Long employee_Id, String employee_first_name, String employee_last_name) { this.Employee_Id = employee_Id; this.Employee_first_name = employee_first_name; this.Employee_last_name = employee_last_name; } }
数据仓库接口
public interface OrganizationRepository<T> { // Save method void save(T entity); // Find a employee by its id Employee findById(Long id); //public List<Employee> findAllEmployees(); }
仓库实现类
@Repository public class EmployeeRepository implements OrganizationRepository<Employee> { private final Map<Long, Employee> repository; public EmployeeRepository() { this.repository = new HashMap<>(); } @Override public void save(Employee employee) { // repository.put(id, employee); repository.put(employee.getEmployeeId(), employee); } @Override public Employee findById(Long id) { Employee employeeOutput = null; if (repository.containsKey(id)) { employeeOutput = repository.get(id); } return employeeOutput; } }
Controller类
@RestController public class EmployeeController { @Autowired private EmployeeRepository employeeRepository; @PostMapping("/employees") public Employee createEmployee(@RequestBody Employee employee) { employeeRepository.save(employee); return employee; } @GetMapping("/employees/findbyid/{id}") public Employee getEmployee(@PathVariable Long id) { return employeeRepository.findById(id); } @GetMapping("/hello") public String hello() { return "Hello, World!"; } }
排查建议
- 仓库实例不共享:主应用类中手动创建的
AnnotationConfigApplicationContext和Spring Boot启动的主上下文完全独立,你手动初始化的数据存储在这个独立上下文的仓库实例中,而Controller注入的是主上下文的仓库实例,两者无关联。删除手动创建上下文的代码,改用CommandLineRunner在主上下文初始化数据:@SpringBootApplication @ComponentScan("com.someone.organization") public class WorkingOrganizationApplication implements CommandLineRunner { @Autowired private EmployeeRepository empRepository; public static void main(String[] args) { SpringApplication.run(WorkingOrganizationApplication.class, args); } @Override public void run(String... args) throws Exception { empRepository.save(new Employee(1L, "XYZ","PQR")); empRepository.save(new Employee(2L, "ABC","PQR")); empRepository.save(new Employee(3L, "MNC","PQR")); System.out.println(empRepository.findById(1L)); System.out.println(empRepository.findById(2L)); } } - 实体类序列化异常:
Employee类的属性名与getter/setter命名不符合JavaBean规范(比如属性Employee_Id对应gettergetEmployeeId(),缺少下划线),导致JSON序列化工具无法正确识别字段,返回空对象。解决方式二选一:- 将属性名改为小驼峰格式(
employeeId、employeeFirstName、employeeLastName),同步修改对应的getter/setter使其符合规范; - 保留原属性名,添加
@JsonProperty注解指定序列化字段名:@JsonProperty("Employee_Id") private Long Employee_Id; @JsonProperty("Employee_Id") public Long getEmployeeId() { return Employee_Id; } @JsonProperty("Employee_Id") public void setEmployee_Id(Long employee_Id) { Employee_Id = employee_Id; }
- 将属性名改为小驼峰格式(
- 空值响应处理:
findById方法找不到数据时返回null,Controller直接返回null会导致响应体为空,建议改用ResponseEntity返回明确状态:@GetMapping("/employees/findbyid/{id}") public ResponseEntity<Employee> getEmployee(@PathVariable Long id) { Employee employee = employeeRepository.findById(id); return employee != null ? ResponseEntity.ok(employee) : ResponseEntity.notFound().build(); } - 实例一致性验证:在Controller和初始化代码中打印仓库实例的哈希值,确认是否为同一个对象:
// Controller中 System.out.println("Controller仓库实例哈希:" + employeeRepository.hashCode()); // 初始化代码中 System.out.println("初始化仓库实例哈希:" + empRepository.hashCode());
内容的提问来源于stack exchange,提问作者crcr
相关产品推荐
相关产品推荐

