From 161c9dc3bd42f2391eaa9f538d4ccad828da1ab0 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Tue, 27 Jul 2021 15:05:43 +0200 Subject: [PATCH] Improve @Cacheable documentation regarding java.util.Optional This commit improves the documentation for @Cacheable to point out that `null` will be stored in the cache for an empty `Optional` return value. Closes gh-27184 --- .../cache/annotation/Cacheable.java | 10 ++++++---- src/docs/asciidoc/integration.adoc | 14 ++++++++------ 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/spring-context/src/main/java/org/springframework/cache/annotation/Cacheable.java b/spring-context/src/main/java/org/springframework/cache/annotation/Cacheable.java index b93cf9373f..e1d2700a4c 100644 --- a/spring-context/src/main/java/org/springframework/cache/annotation/Cacheable.java +++ b/spring-context/src/main/java/org/springframework/cache/annotation/Cacheable.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -38,9 +38,11 @@ import org.springframework.core.annotation.AliasFor; * replace the default one (see {@link #keyGenerator}). * *

If no value is found in the cache for the computed key, the target method - * will be invoked and the returned value stored in the associated cache. Note - * that Java8's {@code Optional} return types are automatically handled and its - * content is stored in the cache if present. + * will be invoked and the returned value will be stored in the associated cache. + * Note that {@link java.util.Optional} return types are unwrapped automatically. + * If an {@code Optional} value is {@linkplain java.util.Optional#isPresent() + * present}, it will be stored in the associated cache. If an {@code Optional} + * value is not present, {@code null} will be stored in the associated cache. * *

This annotation may be used as a meta-annotation to create custom * composed annotations with attribute overrides. diff --git a/src/docs/asciidoc/integration.adoc b/src/docs/asciidoc/integration.adoc index 9e55960525..15e49e487d 100644 --- a/src/docs/asciidoc/integration.adoc +++ b/src/docs/asciidoc/integration.adoc @@ -5688,7 +5688,7 @@ method -- if at least one cache is hit, the associated value is returned. NOTE: All the other caches that do not contain the value are also updated, even though the cached method was not actually invoked. -The following example uses `@Cacheable` on the `findBook` method: +The following example uses `@Cacheable` on the `findBook` method with multiple caches: [source,java,indent=0,subs="verbatim,quotes"] ---- @@ -5896,9 +5896,11 @@ want to cache paperback books, as the following example does: <1> Using the `unless` attribute to block hardbacks. -The cache abstraction supports `java.util.Optional`, using its content as the cached value -only if it is present. `#result` always refers to the business entity and never a -supported wrapper, so the previous example can be rewritten as follows: +The cache abstraction supports `java.util.Optional` return types. If an `Optional` value +is _present_, it will be stored in the associated cache. If an `Optional` value is not +present, `null` will be stored in the associated cache. `#result` always refers to the +business entity and never a supported wrapper, so the previous example can be rewritten +as follows: [source,java,indent=0,subs="verbatim,quotes"] ---- @@ -5906,8 +5908,8 @@ supported wrapper, so the previous example can be rewritten as follows: public Optional findBook(String name) ---- -Note that `result` still refers to `Book` and not `Optional`. As it might be `null`, we -should use the safe navigation operator. +Note that `#result` still refers to `Book` and not `Optional`. Since it might be +`null`, we use SpEL's <>. [[cache-spel-context]] ===== Available Caching SpEL Evaluation Context