Спящий режим EntityManager кэш запросов — «объединенная выборка» не работает

#hibernate #jpa #join #fetch #query-cache

#переход в режим гибернации #jpa #Присоединиться #извлечение #запрос-кэш

Вопрос:

Я пытаюсь кэшировать запрос, подобный этому:

 TypedQuery<Foo> q = em.createQuery(
    "SELECT foo FROM Foo foo "  
    "INNER JOIN FETCH Foo.bar "
);
q.setHint("org.hibernate.cacheable", true);
  

Проблема в том, что FETCH , похоже, не оказывает никакого эффекта при попадании в кэш, т. е. коллекция Foo.bar не инициализируется. Я мог бы выполнить итерацию по списку результатов и инициализировать все экземпляры коллекции вручную, но это сделало бы все это еще медленнее, чем без использования кэша запросов в первую очередь.

Я использую JBoss версии 6.0 / Hibernate 3.6 с Infinispan в качестве механизма кэширования.

Любопытно, что согласно статистике кэша, которую я получаю через консоль JMX, объекты в Foo.bar, похоже, кэшируются, но кэш для этих объектов не получает никаких обращений.

Ответ №1:

Это можно исправить, применив @Cache к свойству collection (конечно, целевой объект также должен быть кэшируемым), см. 21.2.1. Сопоставления кэша.

Комментарии:

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

2. @chris : может быть, вам стоит попробовать посмотреть, может ли EntityGraph соответствовать вашим потребностям.