2008-03-27

NHibernates MemCached feature

Getting started

NHibernate have rich support for caching, one of them is memcached. Getting started was actually easy, I followed this guide.

Download the sample

The VS2005 solution can be downloaded here. It is based on NHibernate NHibernate-1.2.1.GA-src.zip and SQL CE is included.

Using the sample

Memcahed Win32 is included in the solution and 2 instances can be started with memcached1.bat and memcached2.bat. Any activity can be monitored in the console windows.

NHibernate logs to a file called "NHibernateCacheExampleClient\log4net.log", and you should be able to see SQL executed against the database here.

The "Create" button creates a new Person with Id "1" and the name "John Doe". 
The "Get" button loads a Person with Id "1".

If the cache is running and the Person is in the cache, the NHibernate log should not show any SQL execute and the memcached console should show activity.

3 comments:

Chris Carter said...

Thanks, good simple demo.

PabloDG said...

I added a 'modify' button with following code:


protected void Button1_Click(object sender, EventArgs e)
{
using (ISession session = Global.SessionFactory.OpenSession())
{
IDbCommand cmd = session.Connection.CreateCommand();
cmd.CommandType = CommandType.Text;
cmd.CommandText = "update persons set Name = 'changed'";
cmd.ExecuteNonQuery();
}
}

I don' see NHibernate can catch the statement. However, the GET buttons gets 'changed' as the name for the person if I click Create, Get, Modify, Get.

I would have expect second level cache to keep nhibernate from querying the database....

Tim said...

You need to use the Person object in the project to update... Else NHibernate won't know about your change. Add a property for Name then use some code like so:

using (ISession session = Global.SessionFactory.OpenSession())
using (ITransaction transaction = session.BeginTransaction())
{
Person person = session.CreateCriteria(typeof(Person)).Add(Expression.Eq("id", 1)).UniqueResult<Person>();

person.Name = "changed";

transaction.Commit();
}