Fix reactive retrieval of cached null value for empty Mono

Closes gh-31722
This commit is contained in:
Juergen Hoeller 2023-11-30 12:05:16 +01:00
parent f77713b7e0
commit 4a6c3e8f5d
2 changed files with 44 additions and 5 deletions

View File

@ -1068,13 +1068,13 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker
if (adapter.isMultiValue()) {
return adapter.fromPublisher(Flux.from(
Mono.fromFuture(cachedFuture)
.flatMap(value -> (Mono<?>) evaluate(Mono.just(unwrapCacheValue(value)), invoker, method, contexts)))
.flatMap(value -> (Mono<?>) evaluate(Mono.justOrEmpty(unwrapCacheValue(value)), invoker, method, contexts)))
.flatMap(v -> (v instanceof Iterable<?> iv ? Flux.fromIterable(iv) : Flux.just(v)))
.switchIfEmpty(Flux.defer(() -> (Flux<?>) evaluate(null, invoker, method, contexts))));
}
else {
return adapter.fromPublisher(Mono.fromFuture(cachedFuture)
.flatMap(value -> (Mono<?>) evaluate(Mono.just(unwrapCacheValue(value)), invoker, method, contexts))
.flatMap(value -> (Mono<?>) evaluate(Mono.justOrEmpty(unwrapCacheValue(value)), invoker, method, contexts))
.switchIfEmpty(Mono.defer(() -> (Mono) evaluate(null, invoker, method, contexts))));
}
}

View File

@ -202,6 +202,10 @@ class CacheReproTests {
assertThat(bean.findById("tb2").join()).isNotSameAs(tb);
assertThat(cache.get("tb2")).isNull();
assertThat(bean.findByIdEmpty("").join()).isNull();
assertThat(bean.findByIdEmpty("").join()).isNull();
assertThat(cache.get("").get()).isNull();
context.close();
}
@ -226,6 +230,10 @@ class CacheReproTests {
assertThat(bean.findById("tb1").get()).isSameAs(tb);
assertThat(cache.get("tb1").get()).isSameAs(tb);
assertThat(bean.findById("").join()).isNull();
assertThat(bean.findById("").join()).isNull();
assertThat(cache.get("").get()).isNull();
context.close();
}
@ -257,6 +265,10 @@ class CacheReproTests {
assertThat(bean.findById("tb2").block()).isNotSameAs(tb);
assertThat(cache.get("tb2")).isNull();
assertThat(bean.findByIdEmpty("").block()).isNull();
assertThat(bean.findByIdEmpty("").block()).isNull();
assertThat(cache.get("").get()).isNull();
context.close();
}
@ -281,6 +293,10 @@ class CacheReproTests {
assertThat(bean.findById("tb1").block()).isSameAs(tb);
assertThat(cache.get("tb1").get()).isSameAs(tb);
assertThat(bean.findById("").block()).isNull();
assertThat(bean.findById("").block()).isNull();
assertThat(cache.get("").get()).isNull();
context.close();
}
@ -312,6 +328,10 @@ class CacheReproTests {
assertThat(bean.findById("tb2").collectList().block()).isNotEqualTo(tb);
assertThat(cache.get("tb2")).isNull();
assertThat(bean.findByIdEmpty("").collectList().block()).isEmpty();
assertThat(bean.findByIdEmpty("").collectList().block()).isEmpty();
assertThat(cache.get("").get()).isEqualTo(Collections.emptyList());
context.close();
}
@ -336,6 +356,10 @@ class CacheReproTests {
assertThat(bean.findById("tb1").collectList().block()).isEqualTo(tb);
assertThat(cache.get("tb1").get()).isEqualTo(tb);
assertThat(bean.findById("").collectList().block()).isEmpty();
assertThat(bean.findById("").collectList().block()).isEmpty();
assertThat(cache.get("").get()).isEqualTo(Collections.emptyList());
context.close();
}
@ -568,6 +592,11 @@ class CacheReproTests {
return CompletableFuture.completedFuture(new TestBean(id));
}
@Cacheable(value = "itemCache")
public CompletableFuture<TestBean> findByIdEmpty(String id) {
return CompletableFuture.completedFuture(null);
}
@CachePut(cacheNames = "itemCache", key = "#item.name")
public CompletableFuture<TestBean> insertItem(TestBean item) {
return CompletableFuture.completedFuture(item);
@ -584,7 +613,7 @@ class CacheReproTests {
@Cacheable(value = "itemCache", sync = true)
public CompletableFuture<TestBean> findById(String id) {
return CompletableFuture.completedFuture(new TestBean(id));
return CompletableFuture.completedFuture(id.isEmpty() ? null : new TestBean(id));
}
@CachePut(cacheNames = "itemCache", key = "#item.name")
@ -601,6 +630,11 @@ class CacheReproTests {
return Mono.just(new TestBean(id));
}
@Cacheable(value = "itemCache")
public Mono<TestBean> findByIdEmpty(String id) {
return Mono.empty();
}
@CachePut(cacheNames = "itemCache", key = "#item.name")
public Mono<TestBean> insertItem(TestBean item) {
return Mono.just(item);
@ -617,7 +651,7 @@ class CacheReproTests {
@Cacheable(value = "itemCache", sync = true)
public Mono<TestBean> findById(String id) {
return Mono.just(new TestBean(id));
return (id.isEmpty() ? Mono.empty() : Mono.just(new TestBean(id)));
}
@CachePut(cacheNames = "itemCache", key = "#item.name")
@ -636,6 +670,11 @@ class CacheReproTests {
return Flux.just(new TestBean(id), new TestBean(id + (counter++)));
}
@Cacheable(value = "itemCache")
public Flux<TestBean> findByIdEmpty(String id) {
return Flux.empty();
}
@CachePut(cacheNames = "itemCache", key = "#id")
public Flux<TestBean> insertItem(String id, List<TestBean> item) {
return Flux.fromIterable(item);
@ -654,7 +693,7 @@ class CacheReproTests {
@Cacheable(value = "itemCache", sync = true)
public Flux<TestBean> findById(String id) {
return Flux.just(new TestBean(id), new TestBean(id + (counter++)));
return (id.isEmpty() ? Flux.empty() : Flux.just(new TestBean(id), new TestBean(id + (counter++))));
}
@CachePut(cacheNames = "itemCache", key = "#id")