skip to Main Content

I was developing a simple application to learn redis caching. Until I add redis as a caching mechanism on spring boot project the API’s works fine. REST project you can say. Using Postman for calling different API. After adding redis I saw that @CacheEvict which is used for deleting data works fine. But when I call request like GetMapping, PutMapping which annotated with @Cacheable, @CachePut doesn’t work. I don’t understand what is the problem where @CacheEvict working perfectly @Cacheable, @CachePut doesn’t.

Here is the error given by postman when I’m calling API’s using following url:
PUT: http://localhost:8080/bank/2/deposit
GET: http://localhost:8080/bank/holderName/Aysha

{
    "dateTime": "2024-03-30T16:49:17.7557062",
    "message": "Cannot serialize",
    "error": "uri=/bank/2/deposit",
    "path": "Bad Request"
}

Let me explain in more detail how I configured redis:

POM:

<!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
</dependency>

application.properties:

spring.cache.type=redis
spring.cache.redis.time-to-live=60000
spring.cache.redis.host=localhost
spring.cache.redis.port=6379

Account (Entity):

@Entity
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Account implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String holderName;
    private double balance;
}

Here I enabled caching:

@SpringBootApplication
@EnableCaching
public class SimpleBankingApplication {

    @Bean
    public ModelMapper mapper(){
        return new ModelMapper();
    }

    public static void main(String[] args) {
        SpringApplication.run(SimpleBankingApplication.class, args);
    }

}

Controller class:

@Controller
@RequestMapping("bank")
@AllArgsConstructor
@CacheConfig(cacheNames = "account")
public class AccountController {
    private AccountService service;

    @PostMapping("createAccount")
    public ResponseEntity<AccountDTO> createAccount(@RequestBody @Valid AccountDTO dto){
        return new ResponseEntity<>(service.addAccount(dto), HttpStatus.CREATED);
    }
    @GetMapping("holderName/{name}")
    @Cacheable(value = "account", key = "#name")
    public ResponseEntity<AccountDTO> getAccountByName(@PathVariable String name){
        return new ResponseEntity<>(service.getAccount(name),HttpStatus.ACCEPTED);
    }
    @PutMapping("{id}/deposit")
    @CachePut(cacheNames = "account", key = "#id")
    public ResponseEntity<AccountDTO> deposit(@PathVariable Long id, @RequestBody Map<String, Double> request){
        Double value = request.get("balance");
        return new ResponseEntity<>(service.deposit(id,value), HttpStatus.ACCEPTED);
    }
    @PutMapping("{id}/withdraw")
    public ResponseEntity<AccountDTO> withdraw(@PathVariable Long id, @RequestBody Map<String, Double> request){
        Double value = request.get("withdraw_balance");
        return new ResponseEntity<>(service.withdraw(id,value), HttpStatus.ACCEPTED);
    }
    @GetMapping("allAccounts")
    public ResponseEntity<List<AccountDTO>> getAllAccount(){
        return new ResponseEntity<>(service.getAllAccounts(),HttpStatus.ACCEPTED);
    }
    @DeleteMapping("deleteAccount/{id}")
    @CacheEvict(cacheNames = "account", key = "#id", beforeInvocation = true)
    public ResponseEntity<String> deleteAccount(@PathVariable Long id){
        service.delete(id);
        return new ResponseEntity<>("Account has been deleted!!!", HttpStatus.ACCEPTED);
    }
}

Project link: view the project

2

Answers


  1. On your github code, you have changed the annotation @Controller to @RestController on the AccountController. It solved the problem? Because @RestController returns JSON. The next step is try to remove the mapper bean that you’ve created in SimpleBankingApplication class, because Spring manages it with Jackson JSON Mapper by default

    Login or Signup to reply.
  2. Try implementing Serializable

    public class AccountDTO implements Serializable {
    //your fields, constructors, methods etc.
    }
    

    Here is the reference.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search