hanqunfeng / reactive-redis-cache-annotation-spring-boot-starter

Apache License 2.0
11 stars 2 forks source link

Some of aspects doesn't work #1

Open Bryksin opened 2 years ago

Bryksin commented 2 years ago

Used version 1.1.0 from Maven

Problems:

The project used for testing:

MySql Table creation:

CREATE TABLE test_table (
    `id` INT(11) NOT NULL AUTO_INCREMENT,
    `name` VARCHAR(200) NOT NULL UNIQUE,
    `insert_date` timestamp NOT NULL,
    PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Gradle imports:

    //Spring
    implementation 'org.springframework.boot:spring-boot-starter-data-r2dbc'
    implementation 'org.springframework.boot:spring-boot-starter-data-redis-reactive'
    implementation 'org.springframework.boot:spring-boot-starter-webflux'

    //General
    compileOnly 'org.projectlombok:lombok'
    annotationProcessor 'org.projectlombok:lombok'

    //DB
    runtimeOnly 'dev.miku:r2dbc-mysql:0.8.2.RELEASE'

    //Redis Cache
    implementation "com.hanqunfeng:reactive-redis-cache-annotation-spring-boot-starter:1.1.0"

    //Test
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    testImplementation 'io.projectreactor:reactor-test'

application.yml

spring:
  application:
    name: reactive-cache-prototype
  main:
    web-application-type: reactive
  profiles:
    active: dev
---
spring:
  config:
    activate:
      on-profile: dev
  r2dbc:
    username: "root"
    password: "<<your_pass>>"
    schema-name: "reactive_cache_prototype"
    url: r2dbc:mysql://localhost:3306/${spring.r2dbc.schema-name}
  redis:
    host: "localhost"
    port: 6379
    client-name: ${spring.application.name}
    client-type: lettuce

Model:

@Data
@AllArgsConstructor
@NoArgsConstructor
@Table
@Persistent
public class TestTable {
    @Id
    private Integer id;
    private String name;
    @CreatedDate //requires @EnableR2dbcAuditing to be added in main class
    private LocalDateTime insertDate;
}

Repo:

public interface TestTableRepository extends ReactiveCrudRepository<TestTable, Integer> {
    Mono<TestTable> findByName(String name);
    Mono<Void> deleteByName(String name);
}

Controller:

@RestController
@RequiredArgsConstructor
@Slf4j
public class CacheTestController {

    private final TestTableService testTableService;

    //using all GET requests for simplicity

    // /create?name=test
    @GetMapping("/create")
    public ResponseEntity<Mono<TestTable>> createRecord(@RequestParam String name) {
        log.info("Creating record with name: " + name);
        return ResponseEntity.ok(testTableService.createRecord(name));
    }

    @GetMapping("/get/{name}")
    public ResponseEntity<Mono<TestTable>> getByName(@PathVariable String name) {
        log.info("Getting Record by name: " + name);
        return ResponseEntity.ok(testTableService.getByName(name));
    }

    @GetMapping("/delete/{name}")
    public ResponseEntity<Mono<Void>> deleteByName(@PathVariable String name) {
        log.info("Deleting Record by name: " + name);
        return ResponseEntity.ok(testTableService.deleteRecord(name));
    }

    @GetMapping("/update/{id}/{newName}")
    public ResponseEntity<Mono<TestTable>> deleteByName(@PathVariable Integer id, @PathVariable String newName) {
        log.info("Update Record: " + id  + " with new name: " + newName);
        return ResponseEntity.ok(testTableService.updateRecord(id, newName));
    }
}

Service:

@Service
@RequiredArgsConstructor
public class TestTableService {

    private final TestTableRepository testTableRepository;

    private static final String cache = "testTable";

    // works fine  
    @ReactiveRedisCacheable(cacheName = cache, key ="#name")
    public Mono<TestTable> createRecord(String name) {
        TestTable testTable = new TestTable();
        testTable.setName(name);
        return testTableRepository.save(testTable);
    }

    // works fine 
    @ReactiveRedisCacheable(cacheName = cache, key ="#name")
    public Mono<TestTable> getByName(String name) {
        return testTableRepository.findByName(name);
    }

    public Mono<TestTable> updateRecord(Integer id, String newName) {
        return testTableRepository.findById(id).flatMap(foundRec -> updateRecord(foundRec, newName));
    }

    //Doesnt work at all
    @ReactiveRedisCaching(
            evict = {@ReactiveRedisCacheEvict(cacheName = cache, key = "#testTableToUpdate.getName()")},
            put = {@ReactiveRedisCachePut(cacheName = cache, key = "#newName")}
    )
    private Mono<TestTable> updateRecord(TestTable testTableToUpdate, String newName) {
        testTableToUpdate.setName(newName);
        return testTableRepository.save(testTableToUpdate);
    }

    //without 'beforeInvocation = true' doesn't work
    @ReactiveRedisCacheEvict(cacheName = cache, key = "#name", beforeInvocation = true)
    public Mono<Void> deleteRecord(String name) {
        return testTableRepository.deleteByName(name);
    }
}

Used local dockers for MySQL

docker run -d --rm --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD="<<your_pass>>" mysql:5.6

and Redis

docker run -d --rm --name redis -p 6379:6379 redis:6.2.6
hanqunfeng commented 1 year ago

Hello, thank you for using my jar in your project. I haven't maintained this project for a long time and I'm very sorry for the inconvenience caused. I can't reproduce the problem you mentioned, so I suggest using the latest version. It is recommended to enable debug logs to verify whether cache annotations are working.

logging:
  level:
    com.hanqunfeng.reactive.redis.cache: DEBUG