0
@Query(value = "select  student_rid as row_id, student_name as Name from student_data where student_rid=:Student and visibility=true)", nativeQuery = true)
public List<Map<String, String>> findNameAndRowID(@Param("Student") Long Student);

I want to cache the list output, but when I am trying to cache the output the whole List is cached as a single cache entry, and because of this, I have to evict this whole cache(list) entry all the time when I either insert/delete even a single record into the database, which is not what I want as it does not serves the purpose of caching. So is there a way we can cache the list elements as a single entries such that I can only evict/update the single record at any insert/delete statement.

I am using Spring Boot, Java 8, and Spring tool suite as IDE.

John Blum
  • 7,381
  • 1
  • 20
  • 30
  • Well, the first challenge would be what the key for each entry should be, how you would access them individually and how you'd handle cache misses. – Thomas Jun 01 '21 at 07:00
  • Hi @Thomas, lets say that I wanted key as a primary key of the table( like the row_id ), since it is unique for the table. – Manoj kumar Reddy Jun 01 '21 at 07:34

2 Answers2

0

Your use-case seems a little odd since you seem to already only load a single student and only the name of it so I'll try to create a more meaningful example you could build on.

First a disclaimer though: I'm coming from a JavaEE background, haven't used Spring in a while and didn't have a chance to actually test the quickly cobbled together approach I'll describe here so please take it with a grain of salt.

Let's assume you have the following service:

class StudentService {
   @Autowired
   StudentRepository repo;     

   List<Student> loadStudents(someCriteria) {
      return repo.loadStudents(someCriteria);
   }
}

To cache each student you could now introduce a new caching service and call it per student. You might be able to put the method into StudentService but I'm not sure Spring would then be able to inject the necessary handling code (maybe through more advanced AOP and byte-code manipulation).

A simple version could look like this:

class StudentCacheService {
  @CachePut( value = "studentCache", key = "#student.id")
  Student cacheStudent(Student student) {
    return student;
  }
}

class StudentService {
   @Autowired
   StudentRepository repo;     

   @Autowired
   StudentCacheService cacheService;     

   List<Student> loadStudents(someCriteria) {
      List<Student> students = repo.loadStudents(someCriteria);

      //cache each student individually
      students.forEach(s -> cacheService.cacheStudent(s));

      return students;
   }
}

Note that there might be more elegant options like handling it in the cache manager etc. but this should get you started.

Thomas
  • 87,414
  • 12
  • 119
  • 157