NHibernate не находит именованные наборы результатов запроса в кеше 2-го уровня - PullRequest
4 голосов
/ 04 мая 2010

У меня есть простой модульный тест, в котором я выполняю один и тот же именованный запрос NHibernate 2 раза (каждый раз разный сеанс) с одинаковым параметром. Это простой параметр int, и, поскольку мой запрос является именованным запросом, я предполагаю, что эти 2 вызова идентичны и результаты должны быть кэшированы.

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

вот фрагмент из моего журнала (обратите внимание, как отличаются ключи):

(первый запрос)

DEBUG NHibernate.Caches.SysCache2.SysCacheRegion [(null)] <(null)> - добавление новых данных: key = [snipped] ... parameters: ['809']; названный параметры: {} @ 743460424 & значение = System.Collections.Generic.List`1 [System.Object]

(второй запрос)

ОТЛАДКА NHibernate.Caches.SysCache2.SysCacheRegion [(null)] <(null)> - добавление новых данных: key = [snipped] ... parameters: ['809']; названный параметры: {} @ 704749285 & значение = System.Collections.Generic.List`1 [System.Object]

У меня есть NHibernate, настроенный на использование кеша запросов. И у меня эти запросы установлены на cacheable = true. Не знаю, где еще искать. У кого-нибудь есть предложения?

Спасибо
-Mike

1 Ответ

2 голосов
/ 04 мая 2010

Хорошо, я понял это. Я выполнял свой именованный запрос, используя следующий синтаксис:

IQuery q = session.GetNamedQuery("MyQuery")
                .SetResultTransformer(Transformers.AliasToBean(typeof(MyDTO)))
                .SetCacheable(true)
                .SetCacheRegion("MyCacheRegion");

(что, я мог бы добавить, это ТОЧНО , как документы NHibernate говорят вам, как это сделать ... но я отвлекся;))

Если вы используете создание нового преобразователя AliasToBean для каждого запроса, то каждый объект запроса (, который является ключом кеша ) будет уникальным, и вы никогда не получите попадание в кеш. Короче говоря, если вы сделаете это, как говорят документы nhib, то кеширование не сработает.

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

private static IResultTransformer myTransformer = Transformers.AliasToBean(typeof(MyDTO))

...

IQuery q = session.GetNamedQuery("MyQuery")
                    .SetResultTransformer(myTransformer)
                    .SetCacheable(true)
                    .SetCacheRegion("MyCacheRegion");
...