Deepak
Deepak

Reputation: 45

Get value from cache if it exists, else from DB, but don't write back to cache

I have a use case, wherein, if a value exists in the cache, I'll retrieve from it, else, I'll query the DB, and provide the response, but don't want the result to be cached.

I went through different annotations - https://www.baeldung.com/spring-cache-tutorial, but could not find anyone sufficing the use case.

Very simply, I want to do the following:

if value exists in cache
  return value
else
  return valueFromDB()

Since this code is for production services, I want to use annotations, and keep customization as minimum as possible.

Can someone guide me of a useful annotation for the case?

Upvotes: 2

Views: 1702

Answers (1)

xerx593
xerx593

Reputation: 13261

Yes, starting with gs-spring-caching/complete, this:

@Cacheable(cacheNames = "books", unless = "true") // !!!
public Book getSpecial(String isbn) { // ... same as sample
}

..gives us desired behavior:

  • "books" cache is always issued,
  • never written back,
  • and "evicts" nothing.

Adjusting:

  • BookRepository (interface)
  • With a modified test (AppRunner):
    @Override
    public void run(String... args) throws Exception {
          logger.info(".... Fetching books");
          // populates cache with 1 book:
          logger.info("isbn-1234 -->" + bookRepository.getByIsbn("isbn-1234"));
          // always issues, never writes back to - cache:
          logger.info("isbn-1234 -->" + bookRepository.getSpecial("isbn-1234"));
          logger.info("isbn-4567 -->" + bookRepository.getSpecial("isbn-4567"));
          logger.info("isbn-1234 -->" + bookRepository.getSpecial("isbn-1234"));
          logger.info("isbn-4567 -->" + bookRepository.getSpecial("isbn-4567"));
          logger.info("isbn-1234 -->" + bookRepository.getSpecial("isbn-1234"));
          logger.info("isbn-1234 -->" + bookRepository.getSpecial("isbn-1234"));
    }
    
  • add logging to "slow service"

..we can verify:

2022-10-07 14:04:24.917  INFO 7...Runner: .... Fetching books
2022-10-07 14:04:24.933  INFO 7...itory:  not from cache!
2022-10-07 14:04:27.934  INFO 7...Runner: isbn-1234 -->Book{isbn='isbn-1234', title='Some book'}
2022-10-07 14:04:27.937  INFO 7...Runner: isbn-1234 -->Book{isbn='isbn-1234', title='Some book'}
2022-10-07 14:04:27.939  INFO 7...itory:  not from cache!
2022-10-07 14:04:31.042  INFO 7...Runner: isbn-4567 -->Book{isbn='isbn-4567', title='Some book'}
2022-10-07 14:04:31.044  INFO 7...Runner: isbn-1234 -->Book{isbn='isbn-1234', title='Some book'}
2022-10-07 14:04:31.045  INFO 7...itory:  not from cache!
2022-10-07 14:04:34.066  INFO 7...Runner: isbn-4567 -->Book{isbn='isbn-4567', title='Some book'}
2022-10-07 14:04:34.067  INFO 7...Runner: isbn-1234 -->Book{isbn='isbn-1234', title='Some book'}
2022-10-07 14:04:34.068  INFO 7...Runner: isbn-1234 -->Book{isbn='isbn-1234', title='Some book'}


condition="false" gives us "no cache" behavior (so makes no sense on that annotation).

@Cacheable-javadoc

Upvotes: 2

Related Questions