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.
As part of NHibernate Second Level Cache provider architecture, NCache has implemented
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
<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>
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>
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>
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);
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: