Hibernate JPA Кэширование - PullRequest
5 голосов
/ 21 мая 2010

У меня есть таблица с именем Master_Info_tbl . Это справочная таблица:

Вот код таблицы:

 @Entity
@Table(name="MASTER_INFO_T")
 public class CodeValue  implements java.io.Serializable {
 private static final long serialVersionUID = -3732397626260983394L;
 private Integer objectid;
 private String codetype;
 private String code;
 private String shortdesc;
 private String longdesc;
 private Integer dptid;
 private Integer sequen;
 private Timestamp begindate;
 private Timestamp enddate;
 private String username;
 private Timestamp rowlastchange;
 //getter Setter methods

У меня есть сервисный уровень, который вызывает метод

service.findbycodeType ("Code1");


так же, как эта таблица запрашивается для другие типы кода также например code2, code3 и т. д. до code10 , который получает набор результатов из той же таблицы и отображается в раскрывающемся списке страниц jsp, поскольку эти раскрывающиеся списки находятся на 90% страниц, которые я собираюсь кэшировать в глобальном масштабе.

Есть идеи, как этого добиться?

К вашему сведению: я использую JPA и Hibernate со Struts2 и Spring. Используемая база данных - DB2 UDB8.2


@ Паскаль
Большое спасибо за все ваши ответы. Это мне очень помогло. Я реализовал все, что должен был реализовать (думаю). Тем не менее, я не знаю, работает ли кэширование второго уровня или нет. Так как я не вижу ничего в журнале регистрации в файле журнала log4j из кэша, а также в консоли ничего не отображается. Чтобы показать, что реализация кэша второго уровня работает, мне нужно иметь какое-то доказательство и показать его своему менеджеру. Так что я застрял.
Пожалуйста, помогите!
Я знаю, что я очень близок, чтобы закончить, но просто ....
Вот мой код (если вы считаете, что отсутствует или что-то не должно быть там, пожалуйста, дайте мне знать):
Класс сущности

@Entity
@Cache(usage=CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
@Table(name = "CODEVALUE_T")
public class CodeValue implements java.io.Serializable {
//all the field name with getter and setter
}

persistence.xml:

<properties>
            <property name="hibernate.dialect" value="org.hibernate.dialect.DB2Dialect" />
            <property name="hibernate.show_sql" value="false" />
            <property name="hibernate.cache.use_second_level_cache" value="true"/>
            <property name="hibernate.cache.use_query_cache" value="true"/>
            <property name="hibernate.cache.provider_class" value="org.hibernate.cache.EhCacheProvider" />
        </properties>

Уровень обслуживания DAO:

try {
            System.out.println("Calling the findByCodetype() method");
            final String queryString = "select model from CodeValue model where model.codetype"
                    + "= :propertyValue" + " order by model.code";

            Query query = em.createQuery(queryString);
            query.setHint("org.hibernate.cacheable", true);
            query.setParameter("propertyValue", propertyName);
            return query.getResultList();

        } catch (RuntimeException re) {
            logger.error("findByCodetype failed: ", re);
            throw re;
        }

Значение Log4j.property для отображения подробной информации
log4j.category.org.hibernate.cache = DEBUG

код ehcache.xml (он находится в папке src / там же, где находится мой файл struts.xml)

<ehcache>
   <diskStore path="java.io.tmpdir"/>
   <defaultCache
        maxElementsInMemory="10000"
        eternal="false"
        timeToIdleSeconds="6000"
        timeToLiveSeconds="12000"
        overflowToDisk="true"
        diskPersistent="false"
        diskExpiryThreadIntervalSeconds="120"
        />

</ehcache>

Ответы [ 4 ]

13 голосов
/ 21 мая 2010

(...), так как эти выпадающие списки находятся на 90% страниц, я думаю их кэшировать глобально.

Использование кэша запросов было бы очень уместным для этого варианта использования. Поэтому активируйте кэш второго уровня , кешируйте сущность CodeValue (см. 2.2.8. Кэширование сущностей ) и поместите запрос позади findbycodeType в кеше . Для этого используйте:

javax.persistence.Query query = manager.createQuery(...);
query.setHint("org.hibernate.cacheable", true);

И чтобы уточнить, комбинация запроса и значений, предоставленных в качестве параметров для этого запроса, используется в качестве ключа, а значение представляет собой список идентификаторов для этого запроса . Схематично что-то вроде этого:

*--------------------------------------------------------------------------*
|                              Query Cache                                 |
|--------------------------------------------------------------------------|
| [ "from CodeValue c where c.codetype=?", ["Code1"] ] -> [ 1, 2, ... ]    |
| [ "from CodeValue c where c.codetype=?", ["Code2"] ] -> [ 3, 5, 6, ... ] |
*--------------------------------------------------------------------------*

Таким образом, вызов вашего метода с другими аргументами не "очистит предыдущие данные", аргумент является частью ключа (или кэш запроса не будет работать).

Обратите внимание, что это специфично для Hibernate, JPA 1.0 не определяет кэш второго уровня и кеширование запросов.

Смотри также

6 голосов
/ 03 июня 2012

Hibernate печально записывает операторы sql на консоль, даже если попадание происходит из кэша.

Неверно, Hibernate не регистрирует SQL-операторы, если кэш был использован, подтверждено следующей конфигурацией:

persistence.xml:

<property name="hibernate.cache.use_second_level_cache" value="true"/>
<property name="hibernate.cache.use_query_cache" value="true" />

Класс сущности:

@NamedQuery(name = "byNameLike", query = "SELECT p FROM Person p WHERE name like ?1",
  hints = { @QueryHint(name = "org.hibernate.cacheable", value = "true") })

Регистрация:

Enabled org.hibernate.SQL category.
0 голосов
/ 26 октября 2011

Вы ничего не видите в журнале, потому что Cache не информирует вас о том, что вы ударили / пропустили по умолчанию. Используйте statistics="true" в элементе defaultCache, чтобы включить информацию об этом.

Hibernate, к сожалению, записывает операторы sql на консоль, даже если попадание происходит из кэша.

0 голосов
/ 21 мая 2010

Взгляните на функцию кэша запросов в спящем режиме .

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...