Open
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