title: What is the difference between a nhibernate query cache and entity cache when using second level caching?
body: <p>I am trying to setup nhibernate second level caching <a href="http://www.gitshah.com/2012/03/nhibernate-and-caching-part-2.html" rel="noreferrer">and i see in this article,</a> and i am trying to understand the difference between query caching and entity caching.  It says you need to add</p>
  
  <pre><code>    Cache.ReadOnly();  or Cache.ReadWrite();
  </code></pre>
  
  <p>on every single entity mapping like this:</p>
  
  <pre><code>public class CountryMap : ClassMap&lt;country&gt;
  {
     public CountryMap()
     {
        Table("dropdowns");
        Id(x =&gt; x.Id, "pkey");
         Map(x =&gt; x.Name, "ddlong");
        Map(x =&gt; x.Code, "dddesc");
         Where("ddtype = 'COUNTRY'");
         //Informing NHibernate that the Country entity itself is cache-able.
         Cache.ReadOnly();
     }
  </code></pre>
  
  <p>}</p>
  
  <p>But when using nhibernate profiler, i see things hitting the second level cache and I don't have this Cache.ReadOnly() value set.</p>
  
  <p>Is that really required?  Should I be doing this for every single entity (no matter how often that entity changes?).  </p>
  
  <p>If the answer is yes, that i should be doing this for all entities, I saw a page that mentioned there is a risk of setting an entity with this line as it might lead to Select n + 1 query problem if you are trying to join that entity with other entities in a query.  I  am using nhibernate profiler and it looks like someething are hitting the second level cache just from the code below.  In my session setup, i have the following code:</p>
  
  <pre><code>  return configuration
              .Mappings(m =&gt; m.FluentMappings.AddFromAssemblyOf&lt;ApplicationMap&gt;().Conventions.Add(typeof(Conventions)))
              .ExposeConfiguration(
                  c =&gt; {
                      c.SetProperty("cache.provider_class", "NHibernate.Caches.SysCache.SysCacheProvider, NHibernate.Caches.SysCache");
                      c.SetProperty("cache.use_second_level_cache", "true");
                      c.SetProperty("cache.use_query_cache", "true");
                      c.SetProperty("expiration", "86400");
                  })
              .BuildSessionFactory();
  </code></pre>
  
  <p>and i have a generic "Query" method that does this:</p>
  
  <pre><code>   ICriteria c = Session.CreateCriteria(typeof(T));
     c.SetCacheable(true);
     return c.Future&lt;T&gt;().AsQueryable();
  </code></pre>
  
  <p>so basically I am trying to confirm if i setup caching correctly as I see some second level cache hits when I using nhibernate profiler but I have not set the Cache in the entity mapping code.  I am trying to determine if there are other things i need to do to get caching working (or working better)</p>
  
  <p>When I use nhibernate profiler (without having the Cache.ReadWrite() set at an entity level), it still seems like it does hit the second level cache.  (see screenshot below)</p>
  
  <p><img src="https://i.stack.imgur.com/ClUxx.png" alt="enter image description here"></p>