Skip to content

How to cache methods that return the same list of objects, but based on different conditions?

For example, I have 3 methods. All return data from the same repository and convert it to DTO.

How should I annotate them?

Would it be ok to annotate all three with the same @Cacheable("Dishes_DTO")? And what will happen when one of the methods executes after another, will it override data or make duplicates?

public List<DishResponseDTO> getAllToday() {
    List<Dish> dishlsit = dishRepository.getAllByDateAdded(LocalDate.now(clock));
    return dishlsit.stream()
            .map(DishMapper::toDishResponseDTO)
            .collect(Collectors.toList());
}

public List<DishResponseDTO> getAll() {
    List<Dish> dishlsit = dishRepository.findAll();
    return dishlsit.stream()
            .map(DishMapper::toDishResponseDTO)
            .collect(Collectors.toList());
}

public List<DishResponseDTO> getDishHistoryByRestaurant(int restaurantId) {
    return dishRepository.getAllByRestaurantId(restaurantId)
            .stream()
            .map(DishMapper::toDishResponseDTO)
            .collect(Collectors.toList());
}

Answer

In case you use one cache, you need to have separate keys. One approach you could do:

@Cacheable(value="dishdto", key="-1")
public List<DishResponseDTO> getAllToday();

@Cacheable(value="dishdto", key="-2");
public List<DishResponseDTO> getAll();

@Cacheable("dishdto")
public List<DishResponseDTO> getDishHistoryByRestaurant(int restaurantId);

This uses integer keys and expects that the restaurantId will not get negative.

Your question has a lot more aspects to it:

  • Caching queries
  • List results
  • Time dependent results
  • Reporting on movable data, in general

Design problems:

Your current design holds duplicate data in the cache and memory, because all three method results might contain the same dish.

Since its moving data you need to update the cache often, e.g. by setting an expiry parameter (or TTL) on the cache of 5 minutes. This means you will reread the same dish data, although it will probably not change any more. This can be solved by a cache within the repository or databse. Still, you generate the DTO for the same data entry many times.

If things get to evasive, its better to separate the cache for dish dto objects and query results.