Recientemente me encontré con un problema con Infinispan 8.2.1.Final. Tengo algo de caché de lectura en modo de invalidación con el cargador de caché configurado. La configuración de ese caché consta de dos partes. La primera parte es la siguiente plantilla en 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>
La segunda parte es la configuración programática con clases e interfaces de la API de JCache:
new MutableConfiguration<String, User>() .setReadThrough(true).setStoreByValue(true) .setCacheLoaderFactory(FactoryBuilder.factoryOf(UserCacheLoader.class));
UserCacheLoader
es extremadamente simple. Simplemente crea una nueva instancia de User
cada vez que se llama.
Todo funciona bien hasta que llamo al método javax.cache.Cache.removeAll()
. Provoca la siguiente excepción:
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
Después de investigar un poco, encontré el siguiente código en la clase 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; }
Como puede ver, se llama a newMarshalledEntry
utilizando el value
como clave y como valor.
¿Es un error o una característica? ¿Alguien se enfrentó al mismo problema?
PS Parece que este problema también es real para la última versión de Infinispan.