Кэшируются ли собственные SQL-запросы по умолчанию при включенном кеше запросов Hibernate? - PullRequest
8 голосов
/ 21 апреля 2011

Используя Hibernate 3.3.0 и ehcache 1.2.3 с включенным кэшированием 2-го уровня и кэшем запросов, я понял, что следующий код возвращает один и тот же порядковый номер при нескольких вызовах, что привело к ошибке вставки.

        HibernateCallback callback = new HibernateCallback()
        {
            public Object doInHibernate(Session session) throws HibernateException, SQLException {
                StringBuilder strQuery = new StringBuilder();
                strQuery.append("SELECT ");
                strQuery.append(sequenceName);
                strQuery.append(".nextval as nextSequence FROM dual d");

                Query query = session.createSQLQuery(strQuery.toString()).addScalar("nextSequence", Hibernate.STRING);


                return query.uniqueResult();
            }
        };
        return this.hibernateTemplate.execute(callback).toString();

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

query.setCacheable(false);

Это сбивает с толку, поскольку в документах Hibernate четко указано

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

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

1 Ответ

4 голосов
/ 14 февраля 2012

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

Так, например, ключ может быть:

*----------------------------------------------------------------------------------------*
|                                    Query Cache                                         |
|----------------------------------------------------------------------------------------|
| ["select * from table as t where t.id=? and p.column=?", [ 1 , "value"] ] -> [  2 ] ]  |
*----------------------------------------------------------------------------------------*

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

И, кстати, легко узнать, будет ли ваш запрос использовать кеш запросов или нет!Все это находится в файлах журналов под org.hibernate.cache.

И во всех них есть большой улов - если вы запустите свой собственный запрос, он вытеснит все сущности и записи из кэша второго уровня!По крайней мере, до последней версии, которую я использовал!Таким образом, вы можете нормально использовать собственные запросы, но поскольку Hibernate не может решить, что они делают, он очистит кэш, чтобы избежать изменений данных, выполненных этим запросом, не отраженных в объектах кэша.

Таким образом, существует целоемного проблем с кешем запросов, и вы должны рассмотреть, действительно ли вы хотите использовать эту функцию! Взгляните на эту статью или на эту .Я стараюсь избегать использования кешей запросов в своей работе, я использую SLC только для сущностей ...

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