Абстракция Spring Cache с Hazelcast не вытесняет ключ из кеша

В следующей конфигурации мой возвращаемый объект кэшируется, но когда я пытаюсь удалить ключ вручную, он не работает.

@Configuration
@EnableCaching
public class HazelCastConfiguration {

    @Bean
    public HazelcastCacheManager hazelcastCacheManager() {
        return new HazelcastCacheManager(Hazelcast.newHazelcastInstance(hazelcastConfig()));
    }

    @Bean
    public Config hazelcastConfig() {
        return new Config()
                .setInstanceName("hazelcast-instance")
                .addMapConfig(new MapConfig()
                        .setName("myCache")
                        .setMaxSizeConfig(new MaxSizeConfig())
                        .setEvictionPolicy(EvictionPolicy.LRU)
                        .setStatisticsEnabled(true)
                        .setTimeToLiveSeconds(-1));
    }
}

Кешированный метод:

@Override
@Cacheable(value = "myCache", unless = "#result == null", key = "{#someString, #someLong, #someInteger}")
public List<MyReturnObject> methodWithCachedResults (String someString, Long someLong, Integer someInteger) { 
    //my logic 
}

Пример вспомогательного метода:

public void evictKey(String aString, Long aLong, Integer anInteger) {
         IMap<Object, Object> hazelcastCache = Hazelcast.getHazelcastInstanceByName("hazelcast-instance").getMap("myCache");
         hazelcastCache.evict(Arrays.asList(aString, aLong, anInteger));
         logger.info("{}", hazelcastCache.keySet());
    }

Когда я запускаю описанный выше метод, он регистрирует ключ, даже если я принудительно выселил ключ.

Результат тот же, когда я пытаюсь использовать CacheManager:

@Autowired
private HazelcastCacheManager cacheManager;

public void evictKey(String aString, Long aLong, Integer anInteger) {

    cacheManager.getCache("myCache").evict(Arrays.asList(aString, aLong, anInteger));

}

Однако, если я попробую это сделать, он очистит весь кеш, о чем, очевидно, говорится:

public void evictKey(String aString, Long aLong, Integer anInteger) {
      IMap<Object, Object> hazelcastCache = Hazelcast.getHazelcastInstanceByName("hazelcast-instance").getMap("myCache");
      hazelcastCache.clear();
}

Кстати, проверка keySet (). Contains (Arrays.asList ...) возвращает true.


person Community    schedule 02.04.2020    source источник
comment
И что заставляет вас думать, что хранение всех ваших элементов в списке является правильным ключом? Потому что это не так, и потому что это не так, ключи не совпадают, и ничего не будет выселено. Вам следует использовать метод, помеченный знаком @CacheEvict, для удаления элементов из кеша, так как он воссоздает правильный ключ.   -  person M. Deinum    schedule 02.04.2020
comment
На самом деле, я использовал реализацию EhCache раньше, и использование этого списка в качестве ключа сработало как шарм. Мне удалось сохранить элементы в кеше и удалить кеш так же, как я пытаюсь сейчас. Я попытался использовать @CacheEvict и не использовать список, и он по-прежнему говорит, что keySet () содержит объекты SimpleKey, а не вытесняет ключи.   -  person    schedule 02.04.2020
comment
В logger.info("{}", hazelcastCache.keySet()); какой тип возвращаемых ключей? Вы удаляете ключ списка, но если фактический ключ не является списком, он его не найдет.   -  person Neil Stevenson    schedule 03.04.2020
comment
Как я уже сказал, keySet (). Contains (Arrays.asList (aString, aLong, anInteger)) возвращает true. Я имею в виду, есть ли вероятность, что эти списки равны, но не могут быть выселены?   -  person    schedule 03.04.2020
comment
Глядя на фактическую часть интеграции hazelcast, они делают delete вместо evict. Однако, как уже упоминалось, я настоятельно рекомендую использовать аннотацию или абстракцию кеша Spring для выселения вместо прямой попытки доступа к кешу.   -  person M. Deinum    schedule 03.04.2020
comment
Как вы предложили, я попробовал аннотацию @CacheEvict, и SimpleKey to Spring выполнил эту работу, и мне не повезло. Результаты такие же, и ключи из кеша не удаляются.   -  person    schedule 03.04.2020


Ответы (1)


Это далеко не очевидно, но здесь есть две реализации List.

@Cacheable создаст экземпляр java.util.ArrayList.

Arrays.asList создаст экземпляр java.util.Arrays.ArrayList.

Это должно прояснить:

    public void evictKey(String aString, Long aLong, Integer anInteger) {
        IMap<Object, Object> hazelcastCache = Hazelcast.getHazelcastInstanceByName("hazelcast-instance").getMap("myCache");
        java.util.List<Object> keyToEvict = Arrays.asList(aString, aLong, anInteger);
        boolean success = hazelcastCache.evict(Arrays.asList(aString, aLong, anInteger));
        logger.info("Evicted {}, {} ==  {}", keyToEvict, keyToEvict.getClass(), success);
        for (Object key : hazelcastCache.keySet()) {
            logger.info("Remaining key {}, {}", key, key.getClass());
        }
   }
person Neil Stevenson    schedule 03.04.2020