简体   繁体   中英

Implementing a Search feature using multiple Search parameters

I am new to learning spring boot, and I am trying this side project where you can search for an employee using 2 parameters, access_pin and org_name.

Let's suppose the employee I wanna search in the database has the following credentials:

  • access_pin: 1234
  • org_name: PSG

My API should retrieve the employee record who has the above match.

My REST API URL looks like this:

http://localhost:8080/employeeSearch/version1/1234/PSG

When I send in the GET request on PostMan, I get a 500 Error.

PostMan Screenshot

This is the Database Table:

Database table Screenshot

Can I know how does spring handle multiple search parameters and return accurate result from the database?

MY backend code looks like this:

Model: (Employee.java)

package com.example.demo.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;

@Entity
@Table(name = "employeedatabase")
public class Employee {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long employeeId; 
    
    @Column(name = "employee_name")
    private String employeeName;
    
    @Column(name = "access_pin")
    private long accessPin; 
    
    @Column(name = "org_name")
    private String orgName;
    
    public Employee() {
        
    }

    public Employee(String employeeName, String orgName) {
        super();
        this.employeeName = employeeName;
        this.orgName = orgName;
    }

    public long getEmployeeId() {
        return employeeId;
    }

    public void setEmployeeId(long employeeId) {
        this.employeeId = employeeId;
    }

    public String getEmployeeName() {
        return employeeName;
    }

    public void setEmployeeName(String employeeName) {
        this.employeeName = employeeName;
    }

    public long getAccessPin() {
        return accessPin;
    }

    public void setAccessPin(long accessPin) {
        this.accessPin = accessPin;
    }

    public String getOrgName() {
        return orgName;
    }

    public void setOrgName(String orgName) {
        this.orgName = orgName;
    } 
    
    
    
    
    
    
}



Controller: (EmployeeController.java)

package com.example.demo.Controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.example.demo.model.Employee;
import com.example.demo.service.EmployeeService;



@RestController
@RequestMapping("/employeeSearch/version1")
public class EmployeeController {
    
    @Autowired
    private EmployeeService employeeService;

    public EmployeeController(EmployeeService employeeService) {
        super();
        this.employeeService = employeeService;
    }
    
    @GetMapping("{accessPin}/{orgName}")
    public ResponseEntity<Employee> getEmployeeNAme(@PathVariable("accessPin") long accessPin, @PathVariable("orgName") String orgName) {
        Employee result = employeeService.getEmployeeName(accessPin, orgName);
        
        return ResponseEntity.status(HttpStatus.OK).body(result);
    }
    
    
}

Service: (EmployeeService.java)

package com.example.demo.service;

import com.example.demo.model.Employee;

public interface EmployeeService {
    
    Employee getEmployeeName(long accessPin, String orgName) ; 
}

ServiceImpl: (EmployeeServiceImpl.java)

package com.example.demo.serviceImpl;

import java.util.Optional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.example.demo.exception.ResourceNotFoundException;
import com.example.demo.model.Employee;
import com.example.demo.repository.EmployeeRepository;
import com.example.demo.service.EmployeeService;

@Service
public class EmployeeServiceImpl implements EmployeeService{
    
    @Autowired
    private EmployeeRepository employeeRepository;

    @Override
    public Employee getEmployeeName(long accessPin, String orgName) {
        // TODO Auto-generated method stub
//      return null;
        
        Optional<Employee> employeeName = employeeRepository.findById(accessPin);
        
        
        if(employeeName.get().getAccessPin() == accessPin) {
            return employeeName.get(); 
        }
        else {
            throw new ResourceNotFoundException("The employee does not exist. "); 
        }
    }

}

Repository: (EmployeeRepository.java)

package com.example.demo.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import com.example.demo.model.Employee;

@Repository
public interface EmployeeRepository extends JpaRepository<Employee, Long>{
    

}

Based on your entity the field employee_id is your id. When using the findbyId you are searching using the entity's id. Hence when you call the function with '1234' you are getting an empty optional and hitting a null pointer exception when Optional::get is called causing the 500 error. For your use case, you can add a custom function to EmployeeRepository as shown below

Optional<Employee> findByAccessPinAndOrgName(long accessPin, String orgName);

Also when using an Optional value, do check if the value is present before accessing it.

Do refer to the articles below for more help on both subjects:

https://docs.spring.io/spring-data/data-jpa/docs/current/reference/html/#jpa.query-methods.query-creation

https://www.baeldung.com/java-optional

I see three issues in your code.

In your service, you are calling findById but you are passing the accessPin, not the employee ID - employeeRepository.findById(accessPin) . You should add a findByAccessPin function definition to your repository interface.

When dealing with the Optional repository result in your service class, you should call isPresent() on the result before you try to access it with .get() . Calling get on an empty Optional will result in an exception being thrown.

Finally, your EmployeeController constructor is calling super() but the class has no super class.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM