Recently I ran into an issue with Infinispan 8.2.1.Final. I have some read-through cache in invalidation mode with configured cache loader. Configuration of that cache consists of two parts. First part is the following template in XML:
<?xml version="1.0" encoding="UTF-8"?>
<infinispan xmlns="urn:infinispan:config:8.2">
<cache-container default-cache="default">
<transport cluster="jcache-cluster"/>
<invalidation-cache-configuration name="user" mode="SYNC" statistics="true"/>
</cache-container>
</infinispan>
Second part is programmatic configuration with classes and interfaces from JCache API:
new MutableConfiguration<String, User>()
.setReadThrough(true).setStoreByValue(true)
.setCacheLoaderFactory(FactoryBuilder.factoryOf(UserCacheLoader.class));
UserCacheLoader
is extremely simple. It just creates a new instance of User
every time it is called.
Everything works well until I call javax.cache.Cache.removeAll()
method. It causes the following exception:
Caused by: java.lang.ClassCastException: org.infinispan.test.User cannot be cast to java.lang.String
at org.infinispan.test.UserCacheLoader.load(UserCacheLoader.java:40)
at org.infinispan.jcache.embedded.JCacheLoaderAdapter.loadKey(JCacheLoaderAdapter.java:65)
... 40 more
After some investigation I found the following code in class org.infinispan.jcache.embedded.JCacheLoaderAdapter
:
@Override
public MarshalledEntry load(Object key) throws PersistenceException {
V value = loadKey(key);
if (value != null) {
Duration expiry = Expiration.getExpiry(expiryPolicy, Expiration.Operation.CREATION);
long now = ctx.getTimeService().wallClockTime(); // ms
if (expiry == null || expiry.isEternal()) {
return ctx.getMarshalledEntryFactory().newMarshalledEntry(value, value, null);
} else {
long exp = now + expiry.getTimeUnit().toMillis(expiry.getDurationAmount());
JCacheInternalMetadata meta = new JCacheInternalMetadata(now, exp);
return ctx.getMarshalledEntryFactory().newMarshalledEntry(value, value, meta);
}
}
return null;
}
As you can see newMarshalledEntry
is called using value
both as a key and as a value.
Is it bug or feature? Does anyone faced with the same issue?
P.S. It seems that this issue is also actual for the latest version of Infinispan.