Alachisoft.com

Configure NCache as NHibernate Second Level Cache

NHibernate is a popular object-relational mapping (ORM) solution for.NET. And, it is frequently used in high transaction environments where applications face performance and scalability bottlenecks due to database and data storage.

To handle this, NHibernate provides two types of caching, First Level Cache (1st Level Cache) and Second Level Cache (2nd Level Cache). First Level Cache is built-in and tied to user's "Session Object" whereas Second Level Cache provides a pluggable architecture and is tied to "Session Factor" level (meaning at application level). This means that the cache is not affected by user sessions coming and going. You can plug-in a third party cache as NHibernate Second Level Cache.

NCache is an extremely fast and linearly scalable distributed cache for .NET applications. NCache lets your add more cache servers to handle greater transaction loads. You can plug in NCache as NHibernate Second Level Cache.

Setting up NCache as NHibernate Second Level Cache

As part of NHibernate Second Level Cache provider architecture, NCache has implemented ICacheProvider and ICacheinterfaces. As a result, you can configure NCache as NHibernate Second Level Cache without any programming and simply through configuration file changes.

You simply modify your app.config and specify NCache as your second level cache provider and add a property for it. You also enable second level caching and other sub caches of NHibernate in app.config. Here is an example of app.config changes:


<hibernate-configurationxmlns="urn:nhibernate-configuration-2.2">
...
  <session-factory>
  ...
    <property name="cache.provider_class">
      Alachisoft.NCache.Integrations.NHibernate.Cache.NCacheProvider,
      Alachisoft.NCache.Integrations.NHibernate.Cache
    </property>
    <property name="cache.use_second_level_cache">
      true
    </property>
  ...
  </session-factory>
</hibernate-configuration>

<appSettings>
  <add key="ncache.application_id" 
       value="myapp" />
</appSettings>

Configure Cachable Regions

NCache allows each NHibernate region to be configured differently with its own properties for caching objects. For this purpose NCache has a configuration file named NCacheNHibernate.xml, which contains all region configurations used by the NHibernate Second Level Cache. Following is a sample of that configuration file:


<configuration>
  <application-config application-id="myapp"
                      enable-cache-exception="true"
                      default-region-name="default"
                      key-case-sensitivity="false">
    <cache-regions>
      <region name="default"
              cache-name="mycache"
              priority="default"
              expiration-type="none"
              expiration-period="0" />
      <region name="AbsoluteExpirationRegion"
              cache-name="myRegioncache"
              priority="Default"
              expiration-type="sliding"
              expiration-period="180" />
	</cache-regions>
    ...
  </application-config>
</configuration>

Configure Database Synchronization

NCache is a powerful distributed cache for .NET and provides many rich features. One of these features is database synchronization where cache keeps track of database changes and either invalidates a cached item or reloads it if its corresponding data changes in the database.

You can configure NHibernate Second Level Cache provider for NCache to use database synchronization. Just modify NCacheNHibernate.xml configuration file as following:


<configuration>
  <application-config application-id="myapp" 
                      enable-cache-exception="true" 
                      default-region-name="default"
                      key-case-sensitivity="false">
	...
    <database-dependencies>
      <dependency entity-name="nhibernator.BLL.Customer" 
                  type="sql" 
                  sql-statement="SELECT ContactName FROM dbo.Customers
                                 WHERE CustomerID =?" 
                  cache-key-format="depdency.customer:[pk]"/>
    </database-dependencies>
  </application-config>
</configuration>

Configure NHibernate Query Cache

NHibernate provides a feature of query caching where it caches the results of queries in the Second Level Cache. You can enable NHibernate Query Cache in app.config configuration files as following:


<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
  ...
  <session-factory>
  ...
    <property name="cache.use_query_cache">
    true
    </property>
    ...
  </session-factory>
</hibernate-configuration>

Query along with the primary keys of result sets is stored in a default query region named NHibernate.Cache.StandardQueryCache. But, the objects retrieved as a result of query are cached to their respective regions. Additionally, enabling query cache does not cache each query by default. Instead you must set each query as cacheable in the code as following:


IQuery qry = session.CreateQuery("from Customer c").SetCacheable(true);

Benefits of NCache as NHibernate Second Level Cache

If your NHibernate application is running in a multi-server environment then you need distributed cache like NCache as a NHibernate second level cache provider for the following reasons:

  • Linear Scalability: You can scale your application linearly by adding more cache servers as your transaction load increases. This increases both your transaction capacity and your storage capacity.
  • Truly Elastic Cache: NCache is a truly elastic cache with a peer-to-peer cache clustering architecture and rich set of caching topologies like Mirrored, Replicated, Partitioned, and Partition-Replica Cache. This allows you to ensure 100% uptime and no data loss. You get all of this automatically when using NCache with NHibernate.
  • Database Synchronization: You can synchronize the cache with database (SQL Server, Oracle, and OLEDB) so if any data in the database changes, the cache either invalidates or reloads its corresponding cached items. This ensures that you cache is always fresh. You can enable this feature with NHibernate, as shown above.
  • AsyncOperations: NCache has async operations where your application doesn't have to wait even for the cache to be updated. You can enable this with NHibernate.
  • Dynamic Compact Serialization: NCache has its own serialization that is much faster than regular .NET serialization. You can enable this without any code changes. NCache actually generates serialization code at initialization time, compiles it in memory, and uses it for serialize/deserialize operations. You can mix and match this with regular .NET serialization.

What to Do Next?