Query regarding @Cacheable in Spring Boot

48 views Asked by At

I have a Student entity and I am having three different ways to retrieve a Student record using the student_id, student_phone and student_email. The student controller and data retrieval methods are as follows.

Controller:

@GetMapping("/get")
    public ResponseEntity<?> get(@RequestParam(required = false, name = "phone") String phoneNumber,
            @RequestParam(required = false) String email, @RequestParam(required = false) Integer id) {
        try {
            ReadStudentRequestModel res = null;
            if (phoneNumber != null)
                res = studentCRUDService.readStudentUsingPhoneNumber(phoneNumber);
            else if (email != null)
                res = studentCRUDService.readStudentUsingEmail(email);
            else if (id != null)
                res = studentCRUDService.readStudentUsingId(id);
            else throw new BadRequestException("Unable to find Student: wrong parameters provided.");

            Map<String, Object> map = new LinkedHashMap<>();
            map.put("status", 1);
            map.put("message", "Success");
            map.put("data", res);
            return new ResponseEntity<>(map, HttpStatus.OK);
        }catch(BadRequestException e){
            LinkedHashMap<String, Object> map = new LinkedHashMap<>();
            map.put("status", 0);
            map.put("message", "Failed");
            map.put("error", e.getMessage());
            return new ResponseEntity<>(map, HttpStatus.BAD_REQUEST);
        } catch (Exception e) {
            LinkedHashMap<String, Object> map = new LinkedHashMap<>();
            map.put("status", 0);
            map.put("message", "Failed");
            map.put("error", e.getMessage());
            return new ResponseEntity<>(map, HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

Data retrieval methods

@Service
public class StudentCRUDService{
 @Cacheable(value="LibraryManagement_Student", key="#phoneNumber")
    public ReadStudentRequestModel readStudentUsingPhoneNumber(String phoneNumber) throws Exception {
        Student s = repo.getByPhone(phoneNumber);

        return ReadStudentRequestModel.builder()
                .age(s.getAge())
                .name(s.getName())
                .email(s.getEmail())
                .country(s.getCountry())
                .phoneNumber(s.getPhoneNumber())
                .id(s.getId())
                .card(s.getCard())
                .createdOn(s.getCreatedOn())
                .updatedOn(s.getUpdatedOn())
                .build();

    }

    @Cacheable(value="LibraryManagement_Student", key="#email")
    public ReadStudentRequestModel readStudentUsingEmail(String email) throws Exception {

        Student s = repo.getByEmail(email);

        return ReadStudentRequestModel.builder()
                .age(s.getAge())
                .name(s.getName())
                .email(s.getEmail())
                .country(s.getCountry())
                .phoneNumber(s.getPhoneNumber())
                .id(s.getId())
                .card(s.getCard())
                .createdOn(s.getCreatedOn())
                .updatedOn(s.getUpdatedOn())
                .build();
    }

    @Cacheable(value="LibraryManagement_Student", key="#id")
    public ReadStudentRequestModel readStudentUsingId(Integer id) throws Exception {
        Optional<Student> response = repo.findById(id);

        if(response.isEmpty())throw new Error("Student does not exist.");

        Student s = response.get();

        return ReadStudentRequestModel.builder()
                .age(s.getAge())
                .name(s.getName())
                .email(s.getEmail())
                .country(s.getCountry())
                .phoneNumber(s.getPhoneNumber())
                .id(s.getId())
                .card(s.getCard())
                .createdOn(s.getCreatedOn())
                .updatedOn(s.getUpdatedOn())
                .build();

    }
}

Now the problem is with key attribute in @Cacheable annotations. In the above methods you can see in the key attribute I have to give different keys in different cases that is creating inconsistency. For example, Suppose I have fetched same student object using these different objects. Hence three records will be generated for same object in the db. Now if I try to delete that student using id, I will be unable to delete the other two objects from the cache. Please suggest where am I wrong?

....................

0

There are 0 answers