0

I am working on an application where I need to store a bunch of products' info from a corresponding JSON API call into a cache (eh-cache 3).

The way it works is, http requests will come and trying to get the product's info. Internally a method will be called to get the info from the aforementioned JSON API web service. Since the method is marked cacheable, it will check the cache first. Will assume we know how cacheable works here.

Now the problem that I am facing is that the cache contents doesn't get refreshed until there is a request coming in that will access the products' info (therefore accessing the cache). Even though the cache expiry limit is already reached.

So, to solve this issue I have used a scheduler to call the method that will clear the cache and repopulate it by calling the same method that used earlier to get the products' info. Like so:

@Scheduled(fixedRate = 100000)
public void refreshProdInfoCache() throws Exception {
    String cacheName = "prodInfoCache";
    LOGGER.info("Cache Name -> " + cacheName);
    cacheManager.getCache(cacheName).clear();
    cacheManager.getCache(cacheName).put(cacheName, prodService.getProdInfo());
}

However, I am getting the following exception when running the application:

java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
    at org.springframework.web.context.request.RequestContextHolder.currentRequestAttributes(RequestContextHolder.java:131)
    at org.springframework.web.context.support.WebApplicationContextUtils.currentRequestAttributes(WebApplicationContextUtils.java:312)
    at org.springframework.web.context.support.WebApplicationContextUtils.access$400(WebApplicationContextUtils.java:65)
    at org.springframework.web.context.support.WebApplicationContextUtils$RequestObjectFactory.getObject(WebApplicationContextUtils.java:328)
    at org.springframework.web.context.support.WebApplicationContextUtils$RequestObjectFactory.getObject(WebApplicationContextUtils.java:323)
    at org.springframework.beans.factory.support.AutowireUtils$ObjectFactoryDelegatingInvocationHandler.invoke(AutowireUtils.java:301)
    at com.sun.proxy.$Proxy146.getHeader(Unknown Source)

Have anyone any experience on this situation before? Technically I need to refresh the cache contents during non-peak hour. Thus the need to refresh the cache without waiting for users' request.

Slug
  • 67
  • 3
  • I wanted to reproduce this and to be able to help you, but I could not. what am I doing wrong? https://github.com/62mkv/spring-boot-caching-sample. admittedly, it does not use REST JSON API, but that's not the cause of your exception. – 62mkv Mar 03 '21 at 20:20
  • 1
    Perhaps I should share more of the codes as I'm not exactly very good at explaining. I will try to upload to github after neutralizing the codes. Suspect it is due to ServletContext though. – Slug Mar 04 '21 at 02:37
  • what is "neutralizing" ? I would be happy to learn how to neutralize my code, as it's very hostile occasionally :) otherwise, for whatever reason, it seems that the cacheManager you inject in the class that has the scheduled method, is request- or session-scoped. which.. it shouldn't be. so if you could share a minimal runnable sample, I could try to figure it out – 62mkv Mar 04 '21 at 07:40

1 Answers1

-1

You can use cron for your purpose.

First of all, add it to the method, then enable Schedule in your Application class.

@Scheduled(cron = "0 0 0/1 * * *")
    public void fetchData() {
       
    }
@EnableScheduling
@SpringBootApplication
public class Application {

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

}
Faramarz Afzali
  • 726
  • 1
  • 10
  • 24