Hibernate 2-го уровня кеширование не работает - PullRequest
6 голосов
/ 29 июня 2010

В настоящее время я пытаюсь заставить работать спящий режим с помощью поставщика кэширования, который поставляется с hibernate.

net.sf.ehcache.hibernate.SingletonEhCacheProvider

У меня есть кеш по умолчанию и кеш для конкретного класса, включенный в ecache.xml, на который есть ссылка в моем файле hibernate.cfg.xml. Кэш, относящийся к классу / файлу отображения, определен для обработки до 20000 объектов.

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

Мой тест выглядит следующим образом.

Загрузите 10000 объектов конкретного файла сопоставления, который я тестирую (это должно ударить по БД и стать бутылочным горлышком). Затем я собираюсь загрузить те же 10000 объектов, поскольку в этот момент я ожидаю, что кэш будет поражен и увидит значительный прирост производительности. Попытался использовать сопоставление кэша «только для чтения» и «чтение и запись» в XML-файле hibernate mapping, с которым я тестирую.

Мне интересно, нужно ли им что-то делать, чтобы убедиться, что кэш загружается перед БД при загрузке объектов?

Обратите внимание, что в рамках теста я пролистываю эти 10000 записей, используя что-то похожее на приведенное ниже (подкачка 1000 записей за раз).

Criteria crit = HibernateUtil.getSession() .createCriteria( persistentClass );
       crit.setFirstResult(startIndex);
       crit.setFetchSize(fetchSize);
       return crit.list();

Видели, что у критериев есть установщик режима кэширования (setCacheMode()), так что я должен делать с этим ??

Я замечаю, используя приведенный ниже код статистики, что в памяти есть 10000 объектов (хорошо, я думаю, обезвоженные объекты), но по какой-то причине я получаю 0 хитов и более тревожно 0 промахов, так что похоже, что он вообще не попадает в кэш, когда выполняет поиск, даже несмотря на то, что код статистики говорит мне, что в памяти 10000 объектов.

Есть идеи, чем я занимаюсь? Я полагаю, тот факт, что я получаю промахи, хорош, так как это означает, что кеш используется, но я не могу понять, почему я не получаю никаких попаданий в кеш. Это до того, что я использую setFirstResult() и setFetchSize() с критериями.

System.out.println("Cache Misses = " + stats.getSecondLevelCacheMissCount());
System.out.println("Cache Hits Count = " + stats.getSecondLevelCacheHitCount());

System.out.println("2nd level elements in mem "+ stats.getSecondLevelCacheStatistics("com.SomeTestEntity").getElementCountInMemory());

1 Ответ

13 голосов
/ 30 июня 2010

Кэш второго уровня работает для «поиска по первичному ключу». Для других запросов вам необходимо кэшировать запрос (при условии, что кеш запросов включен), в вашем случае используйте Criteria#setCacheable(boolean):

Criteria crit = HibernateUtil.getSession().createCriteria( persistentClass );
crit.setFirstResult(startIndex);
crit.setFetchSize(fetchSize);
crit.setCachable(true); // Enable caching of this query result
return crit.list();

Предлагаю прочитать:


Если я кеширую запрос, все ли эти спящие сущности из запроса будут доступны в кеше второго уровня?

Да, они будут. Это объясняется черным по белому в ссылке, которую я упомянул: "Обратите внимание, что кэш запросов не кэширует состояние фактических сущностей в наборе результатов; он кэширует только значения идентификаторов и результаты типа значений. Таким образом, кэш запросов всегда следует использовать вместе с кэшем второго уровня ". Вы читали это?

Поскольку у меня сложилось впечатление, что использование кэша запросов совершенно отличается от использования кэша 2-го уровня гибернации.

Он отличается («ключ», используемый для записи в кэш, отличается). Но кеш запросов опирается на кеш L2.

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

Я просто говорю, что вам нужно кэшировать запрос, поскольку вы не "находите по первичному ключу". Я не понимаю, что не ясно. Вы пытались вызвать setCacheable(true) для объекта запроса или критерия? Извините за настойчивость, но вы прочитали ссылку, которую я разместил?

...