Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Redis save POJO as different types when using @Cacheable or @CachePut

I have students which I would like to save both in DB and in Redis cache for improving performance.

I have the Student POJO:

@NoArgsConstructor
@AllArgsConstructor
@Builder
@Data
@RedisHash("Student")
public class Student implements Serializable, RedisElement {

    private static final long serialVersionUID = 4555735174035964832L;
    public enum Gender {
        MALE, FEMALE
    }
    @Id
    private String id;
    private String name;
    private Gender gender;
    private int grade;

}

Used in StudentRepository:

@Repository
public interface StudentRepository extends CrudRepository<Student, String>{

}

I have service which can add, find and delete student:

@Service
public class StudentsService {
    @Cacheable(value = "Student", key = "#id")
    public Student findById(String id) {
        // simulates getting it from db
        Student studentFromDB = Student.builder().id(id).name("db user " + id)
                    .gender((new Random()).nextDouble() > 0.5 ? Gender.FEMALE : Gender.MALE)
                    .grade((new Random()).nextInt(100)).build();
            return studentFromDB;// will be cached next time
    }
    
    @CachePut(value = "Student", key = "#id")
    public Student add(Student student) {
        System.out.println("added student " + student);
        return student;
    }
}

Running my application with RedisApplication:

@SpringBootApplication
@EnableAutoConfiguration
@EnableRedisRepositories
public class RedisApplication {
    
    public static void main(String[] args) {
        SpringApplication.run(RedisApplication.class, args);
    }
}

Whenever I call explicitly to the studentrepository.save(student) method , it calls Redis HMSET and SADD commands to add the student to the cache, but when I use Spring @Cachaeble to do that, it uses the Redis Set command to add the student.

How can I configure @Cachaeble or @CachePut to treat student object the way that calling explicitly will use the Redis HMSET and SADD commands?

like image 476
Erez Levi Avatar asked Nov 23 '25 20:11

Erez Levi


1 Answers

AFAIK, I am afraid that the implementation of the cache mechanism is tightly coupled in the library.

All the actual interactions with Redis are performed by DefaultRedisCacheWriter which is package scoped.

The following code is the one corresponding to the put (cache) operation.

As described in the Spring Data Redis documentation, probably the way to go will be providing your own RedisCacheWriter, I assume based on DefaultRedisCacheWriter with the necessary modifications, and configure Spring cache RedisCacheManager appropriately:

RedisCacheWriter cacheWriter = // Provide your custom implementation...
RedisCacheManager cm = RedisCacheManager.build(cacheWriter)
    .cacheDefaults(defaultCacheConfig())
    ...
like image 166
jccampanero Avatar answered Nov 25 '25 09:11

jccampanero



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!