JCache creates a cache with a list of items for each key (generic)
I want a cache with a list of items. Here is my bean definition:
public Cache<Integer, List<Application>> getMyCacheManager(CacheManager manager) {
Cache<Integer, List<Application>> cache = manager.getCache("myCache");
if (Objects.isNull(cache)) {
var config = new MutableConfiguration<Integer, List<Application>>()
.setTypes(Integer.class, List.class)
.setStoreByValue(false)
.setStatisticsEnabled(true)
.setExpiryPolicyFactory(CreatedExpiryPolicy.factoryOf(new Duration(TimeUnit.MILLISECONDS, myCacheExpiry)));
cache = manager.createCache("myCache", config);
}
return cache;
}
The problem is the .setTypes line.
Here you have to specify the key and value types for the cache. Key is simple, but the value is of the List<Application>
type. You can’t just say: List<Application>.class
because that’s not allowed. And you can’t use List.class
because the compiler hints that the types are not compatible.
I
really want to keep specific types (e.g. List<Application>
otherwise I would have to convert the value from Object
to the correct type every time.
Any ideas?
Solution
The JSR107/JCache specification attempts to include types in the configuration. For collection types, this can cause confusion just like you do.
Unfortunately, you need to add a cast for the correct type to use. The compiler disables direct conversion, so you need to convert to Object
or just Cache
first.
<pre class=”lang-java prettyprint-override”>public Cache<Integer, List<Application>> getMyCacheManager(CacheManager manager) {
Cache<Integer, List<Application>> cache = manager.getCache("myCache");
if (Objects.isNull(cache)) {
var config = new MutableConfiguration<Integer, List<Application>>()
.setTypes(Integer.class, List.class)
.setStoreByValue(false)
.setStatisticsEnabled(true)
.setExpiryPolicyFactory(CreatedExpiryPolicy.factoryOf(new Duration(TimeUnit.MILLISECONDS, myCacheExpiry)));
cache = (Cache<Integer, List<Application>>) ((Object) manager.createCache("myCache", config));
}
return cache;
}
The cache may check for types or use the type information you provide to make some optimizations. For example. cache2k will optimize integer keys and store keys as primitive types, not objects.
Explicit type checking in the cache is not part of the JSR107 specification. This means that for different JCache implementations, you may or may not store any type of object, regardless of what you specify in the configuration. Typically, a cache (setStoreByValue (false))
stores any object references without additional checks. The latter is just unnecessary overhead.
Some parts of JSR107 do talk about runtime type checking. This is to ensure that the cache manager returns a type-compatible cache, rather than forcing only objects of the specified type into the cache. The strict type checking was removed in the service release because it proved to be impractical. Related discussions can be found at: https://github.com/jsr107/jsr107spec/issues/340