почему кеш гуавы может хранить только ненулевое значение в локальном кеше и как обойти это

Я добавляю локальный кеш на свой сервер с помощью утилит Google Guava.

guava очень подходит для моего сценария, за исключением того, что он может хранить только "ненулевые" значения в своем локальном кеше (как com.google.common.cache.Cache, так и com.google.common.cache.LoadingCache).

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

может кто-нибудь сказать мне, почему гуава имеет это ограничение и как я могу его обойти? может ли ehcache больше подойти для моего случая?


person Brian HU    schedule 27.08.2013    source источник


Ответы (4)


Вы действительно хотите кэшировать null (или что-нибудь, представляющее «отсутствует»), если вы просто теряете время, пытаясь получить значение из удаленной базы данных? Вместо этого вы можете создать исключение, которое будет указывать на то, что произошел сбой при получении значения (в отличие от значения, которое просто не существует), а также не добавлять ничего в кеш, чтобы при повторной попытке получить значение для ключа он снова попытается прочитать из базы данных.

person ColinD    schedule 27.08.2013
comment
да, нулевой объект - это не то, что мне нужно, потому что они также будут храниться в локальном кеше, как и значение по умолчанию, а это не то, что я хочу. - person Brian HU; 28.08.2013
comment
моя проблема была решена путем создания фиктивного исключения. хотя я не думаю, что это достаточно подходящее. - person Brian HU; 10.09.2013

Гуава на самом деле не дружелюбна к нулю. Предлагаю вам прочитать их манифест о null [1].

Если вам нужно обойти такое поведение, работайте с Optional<V> [2]. Поэтому вместо работы с LoadingCache<K, V> и CacheLoader<K, V> используйте LoadingCache<K, Optional<V>> и CacheLoader<Optional<V>>.

Таким образом, вы продолжите использовать мощь Cache и добавите гибкости, которую предлагает Optional.

  1. http://code.google.com/p/guava-libraries/wiki/UsingAndAvoidingNullExplained
  2. http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/base/Optional.html.
person Olivier Grégoire    schedule 27.08.2013
comment
спасибо за советы, это действительно помогает. - person Brian HU; 28.08.2013
comment
И, конечно же, как говорит ColinD, когда вам нужно выбросить исключение, выбросьте его! - person Olivier Grégoire; 29.08.2013

Вы можете использовать шаблон проектирования нулевого объекта http://en.wikipedia.org/wiki/Null_Object_pattern

person Evgeniy Dorofeev    schedule 27.08.2013
comment
гм ... я думаю, что нулевой объект - это не то, что мне нужно. но все равно спасибо. - person Brian HU; 28.08.2013

В ehcache вы можете различать нулевое значение и несуществующий ключ, но вам нужен дополнительный класс Element.

// ehcache
cache.put(new Element("key1", null));
assertNull(cache.get("key1").getObjectValue());  // null value
assertNull(cache.get("key2"));  // key is not exist

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

// plain guava
cache.put("key1", "value1");
assertNull(cache.getIfPresent("key2"));  // key is not exist

Как говорили другие, вы можете использовать шаблон нулевого объекта или Optional с гуавой. С таким дополнительным классом вы можете обрабатывать значение null, например ehcache.

// guava with Optional
cache.put("key1", Optional.absent());
assertFalse(cache.getIfPresent("key1").isPresent());  // null value
assertNull(cache.getIfPresent("key2"));  // key is not exist
person takagiko    schedule 27.08.2013
comment
Спасибо за ваше предложение. - person Brian HU; 28.08.2013