Именованный запрос NHibernate и кеш 2-го уровня

У меня есть следующее отображение

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
               assembly="Domain.Core"
               namespace="Domain.Core">
<class name="Industry" table="INDUSTRY">
<cache usage="read-write" region="IndustryCache" include="all"/>
<id name="Id" type="Int64" column="IID">
  <generator class="sequence">
    <param name="sequence">INDUSTRY_SEQ</param>
  </generator> 
</id>
<version name="Version" column="VERSION" access="property" unsaved-value="null" generated="never"/>
<property name="CreationTime" column="CREATE_DATE" type="DateTime" not-null="true" />
<property name="CreatedBy" column="CREATE_USER" type="String" not-null="true" />
<property name="LastUpdateTime" column="MODIFY_DATE"  type="DateTime" not-null="false" />
<property name="LastUpdateBy" column="MODIFY_USER" type="String" not-null="false" />
<property name="Code" column="INDUSTRY" type="String" not-null="false" />
<map name="Resources" table="INDUSTRY_TL"  fetch="subselect">
  <cache region="IndustryCache" usage="read-write" include="all"/>
  <key column="INDUSTRY_ID"/>
  <composite-index class="Framework.Globalization.UILanguage, Framework">
    <key-property name="Code" column="LANG" access="property" />
  </composite-index>
  <composite-element class="Industry+Translation">
    <property name="Name" column="Industry_TL" />
  </composite-element>
</map>
</class>
<query name="GetIndustyOrderByName">
<![CDATA[
from Industry as i left join fetch i.Resources as res where INDEX(res) = :lang order  
by res.Name
]]>
</query>    
</hibernate-mapping>

и следующая конфигурация в hibernate.cfg.xml

<property name="show_sql">true</property>
<property name='proxyfactory.factory_class'>NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle</property>
<property name='prepare_sql'>true</property>
<property name='query.substitutions'>Y=true,N=false,0=false,1=true</property>
<property name="generate_statistics">true</property>
<property name="cache.use_second_level_cache">true</property>
<property name="cache.provider_class">Framework.Cache.SossCacheProvider, Framework.Cache.SossNHibernateCache</property>
<property name="cache.use_query_cache">true</property>

Теперь, когда я запускаю именованный запрос с SetCacheable (true), который вызывает сопоставленную коллекцию, он не попадает в кеш 2-го уровня. Есть ли причина почему?

В общем, есть ли способ поместить набор результатов именованного запроса в кеш второго уровня?

Спасибо!


person Herman    schedule 03.11.2009    source источник


Ответы (1)


Чтобы запросы использовали кеш второго уровня, необходимо сделать две вещи:
1. Включите кеш запросов в конфигурации NHibernate:

    <property name="cache.use_query_cache">true</property>

2. Включите запрос на кеширование при получении экземпляра IQuery:

    IQuery = session.GetNamedQuery("from Industry as i left join fetch i.Resources as res where INDEX(res) = :lang order by res.Name")
      .SetCacheable(true)
      .Setxxx();

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

person Sean Carpenter    schedule 04.11.2009
comment
У меня все это настроено, и NHProf сообщает мне, что я не попадаю в кеш 2-го уровня. Единственная разница в том, что кэшируемое имя определяется в файле hbml.xml, а не в коде. - person Herman; 04.11.2009
comment
Думаю, нужны подробности. Полное сопоставление промышленного класса и файла конфигурации NH было бы хорошим началом. - person Sean Carpenter; 04.11.2009