- 
                Notifications
    You must be signed in to change notification settings 
- Fork 38.8k
Open
Labels
in: coreIssues in core modules (aop, beans, core, context, expression)Issues in core modules (aop, beans, core, context, expression)type: bugA general bugA general bug
Milestone
Description
Henri Tremblay opened SPR-15915 and commented
If I use @Async and @CacheEvict on the same class, calling the method with @CacheEvict directly won't evict anymore.
Let's say I have the following class.
public class MyClass {
  private CountDownLatch latch;
  private MyClass meWithAProxy;
  @Autowired
  ApplicationContext applicationContext;
  @PostConstruct
  public void init() {
    meWithAProxy = applicationContext.getBean(MyClass.class);
  }
  public CountDownLatch getLatch() {
    return latch;
  }
  public void setLatch(CountDownLatch latch) {
    this.latch = latch;
  }
  @Async
  public void function1() {
    meWithAProxy.anotherFunction(123);
    if(latch != null) {
      latch.countDown();
    }
  }
  @CacheEvict(cacheNames = "cache", key = "#testId")
  public List<Integer> anotherFunction(int testId) {
    return Collections.emptyList();
  }
}And I then use it like that:
@Configuration
@EnableCaching
@EnableAsync
public class App {
  public static void main(String[] args) throws InterruptedException {
    ApplicationContext context = new AnnotationConfigApplicationContext(App.class);
    CacheManager cacheManager = context.getBean(CacheManager.class);
    Cache cache = cacheManager.getCache("cache");
    MyClass myClass = context.getBean(MyClass.class);
    cache.put(123, "test"); // value to evict
    myClass.setLatch(new CountDownLatch(1));
    myClass.function1(); // this is correctly called asynchronously
    myClass.getLatch().await();
    assertThat(cache.get(123)).describedAs("Reentrant call failed").isNull(); // and the value is evicted as expected
    cache.put(1, "test"); // new value to evict
    assertThat(cache.get(1)).isNotNull();
    myClass.anotherFunction(1); // direct call
    assertThat(cache.get(1)).describedAs("Direct call failed").isNull(); // fails!
  }
  @Bean
  public MyClass myClass() {
    return new MyClass();
  }
  @Bean
  public TaskExecutor taskExecutor() {
    return new SimpleAsyncTaskExecutor();
  }
  @Bean
  public CacheManager cacheManager() {
    javax.cache.CacheManager cacheManager = Caching.getCachingProvider().getCacheManager();
    cacheManager.createCache("cache", new MutableConfiguration<>().setStoreByValue(false));
    return new JCacheCacheManager(cacheManager);
  }
}For some reason, the cache interceptor is not there. It seems that the Advisors with the cache are replaced by the async ones but I don't know why.
Affects: 4.3.10
Issue Links:
- Scheduled method is not invoked via proxy [SPR-13914] #18488 Scheduled method is not invoked via proxy
Metadata
Metadata
Assignees
Labels
in: coreIssues in core modules (aop, beans, core, context, expression)Issues in core modules (aop, beans, core, context, expression)type: bugA general bugA general bug