DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Last call! Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • Choosing the Right Caching Strategy
  • That Can Not Be Tested!: Spring Cache and Retry
  • How to Connect Redis Sentinel With Spring
  • Working With Spring Boot and Hazelcast (Distributed Cache)

Trending

  • How to Practice TDD With Kotlin
  • Memory Leak Due to Time-Taking finalize() Method
  • Docker Base Images Demystified: A Practical Guide
  • Docker Model Runner: Streamlining AI Deployment for Developers
  1. DZone
  2. Data Engineering
  3. Data
  4. Spring 3.1 Caching and @CacheEvict

Spring 3.1 Caching and @CacheEvict

By 
Roger Hughes user avatar
Roger Hughes
·
Sep. 21, 12 · Interview
Likes (7)
Comment
Save
Tweet
Share
123.0K Views

Join the DZone community and get the full member experience.

Join For Free

My last blog demonstrated the application of Spring 3.1’s @Cacheable annotation that’s used to mark methods whose return values will be stored in a cache. However, @Cacheable is only one of a pair of annotations that the Guys at Spring have devised for caching, the other being @CacheEvict.

Like @Cacheable, @CacheEvict has value, key and condition attributes. These work in exactly the same way as those supported by @Cacheable, so for more information on them see my previous blog: Spring 3.1 Caching and @Cacheable.

@CacheEvict supports two additional attributes: allEntries and beforeInvocation. If I were a gambling man I'd put money on the most popular of these being allEntries. allEntries is used to completely clear the contents of a cache defined by @CacheEvict's mandatory value argument. The method below demonstrates how to apply allEntries:

  @CacheEvict(value = "employee", allEntries = true)
  public void resetAllEntries() {
    // Intentionally blank
  }

resetAllEntries() sets @CacheEvict’s allEntries attribute to “true” and, assuming that the findEmployee(...) method looks like this:
  @Cacheable(value = "employee")
  public Person findEmployee(String firstName, String surname, int age) {

    return new Person(firstName, surname, age);
  }

...then in the following code, resetAllEntries(), will clear the “employees” cache. This means that in the JUnit test below employee1 will not reference the same object as employee2:
  @Test
  public void testCacheResetOfAllEntries() {

    Person employee1 = instance.findEmployee("John", "Smith", 22);
    instance.resetAllEntries();
    Person employee2 = instance.findEmployee("John", "Smith", 22);

    assertNotSame(employee1, employee2);
  }

The second attribute is beforeInvocation. This determines whether or not a data item(s) is cleared from the cache before or after your method is invoked.

The code below is pretty nonsensical; however, it does demonstrate that you can apply both @CacheEvict and @Cacheable simultaneously to a method.
  @CacheEvict(value = "employee", beforeInvocation = true)
  @Cacheable(value = "employee")
  public Person evictAndFindEmployee(String firstName, String surname, int age) {

    return new Person(firstName, surname, age);
  }

In the code above, @CacheEvict deletes any entries in the cache with a matching key before @Cacheable searches the cache. As @Cacheable won’t find any entries it’ll call my code storing the result in the cache. The subsequent call to my method will invoke @CacheEvict which will delete any appropriate entries with the result that in the JUnit test below the variable employee1 will never reference the same object as employee2:

  @Test
  public void testBeforeInvocation() {

    Person employee1 = instance.evictAndFindEmployee("John", "Smith", 22);
    Person employee2 = instance.evictAndFindEmployee("John", "Smith", 22);

    assertNotSame(employee1, employee2);
  }

As I said above, evictAndFindEmployee(...) seems somewhat nonsensical as I’m applying both @Cacheable and @CacheEvict to the same method. But, it’s more that that, it makes the code unclear and breaks the Single Responsibility Principle; hence, I’d recommend creating separate cacheable and cache-evict methods. For example, if you have a cacheing method such as:

  @Cacheable(value = "employee", key = "#surname")
  public Person findEmployeeBySurname(String firstName, String surname, int age) {

    return new Person(firstName, surname, age);
  }

then, assuming you need finer cache control than a simple ‘clear-all’, you can easily define its counterpart:

  @CacheEvict(value = "employee", key = "#surname")
  public void resetOnSurname(String surname) {
    // Intentionally blank

  }

This is a simple blank marker method that uses the same SpEL expression that’s been applied to @Cacheable to evict all Person instances from the cache where the key matches the ‘surname’ argument.
  @Test
  public void testCacheResetOnSurname() {

    Person employee1 = instance.findEmployeeBySurname("John", "Smith", 22);
    instance.resetOnSurname("Smith");
    Person employee2 = instance.findEmployeeBySurname("John", "Smith", 22);
    assertNotSame(employee1, employee2);
  }


In the above code the first call to findEmployeeBySurname(...) creates a Person object, which Spring stores in the “employee” cache with a key defined as: “Smith”. The call to resetOnSurname(...) clears all entries from the “employee” cache with a surname of “Smith” and finally the second call to findEmployeeBySurname(...) creates a new Person object, which Spring again stores in the “employee” cache with the key of “Smith”. Hence, the variables employee1, and employee2 do not reference the same object.

Having covered Spring’s caching annotations, the next piece of the puzzle is to look into setting up a practical cache: just how do you enable Spring caching and which caching implementation should you use? More on that later...
Cache (computing) Spring Framework

Published at DZone with permission of Roger Hughes, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Choosing the Right Caching Strategy
  • That Can Not Be Tested!: Spring Cache and Retry
  • How to Connect Redis Sentinel With Spring
  • Working With Spring Boot and Hazelcast (Distributed Cache)

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!