For quite some time we've been using the @cacheable annotation in our application to enable cache on designated use cases. As a default behavior, any flow passing through the annotated method is cached by the calling method (with arguments, if applicable) as key and the returned value as the cached value. EhCache uses an Element object to keep records in the cache store so that even if we return null from methods, an element entry will be cached (EhCache also stores thrown exceptions if you wish it).
But what if we don't want to cache nulls? There isn't any configuration attribute you can set to prevent such behavior. So how do we handle such a scenario? We can write a CacheEventListener to remove null value entries. The CacheEventListener can look something like this:
EhCache requires a factory to be declared in order to enable it to use our customized listener. Since my event listener is stateless, it can be used as a single instance. So my corresponding factory can look as follows:
Now we need to tell EhCache to enable this factory on cache events. ehcache.xsd supports declaring cache event listener factory per cache configuration. Declaring such factory on the target cache is as follows:
Now elements are removed if their cached value is null. Use wisely.