Set up caching on entities and relationships in Fluent Nhibernate?

Emil C picture Emil C · Oct 1, 2009 · Viewed 9.4k times · Source

Does anyone have an example how to set up and what entities to cache in fluent nhibernate. Both using fluent mapping and auto mapping?

And the same for entity relationships, both one-to-many and many-to-many?

Answer

Dai Bok picture Dai Bok · Nov 24, 2009

I have been working a a similar situation, where I just want to cache specific elements, and want these elements to be loaded once on start up, and kept in cache, until the application is shut down. This is a read only cache, and is used to populate a list of countries, so that a user can select their country from the list.

I used fluentNhibernate Mappings, and defined Country my class with Cache.readonly()

public class CountryMap : ClassMap<Country> {
    public CountryMap() { 
         Schema("Dropdowns");
         Cache.ReadOnly();
         // Class mappings underneath 
    }
}

My user class map looks like this:

public class UserMap : ClassMap<User> {
    Id(x => x.Id).Column("UserId");
    Map(x => x.FirstName);
    Map(x => x.LastName);
    References(x => x.Country)
      .Column("CountryId");
}

I manually configure Fluent Nhibernate to use Second level cache. So in my fluent Confuguration I have:

var sessionFactory = Fluently.Configure()
    .Database (...) // set up db here
    .Mappings(...)  //set up mapping here
    .ExposeConfiguration(c => {
        // People advice not to use NHibernate.Cache.HashtableCacheProvider for production
        c.SetProperty("cache.provider_class", "NHibernate.Cache.HashtableCacheProvider");
        c.SetProperty("cache.use_second_level_cache", "true");
        c.SetProperty("cache.use_query_cache", "true");
    })
    .BuildSessionFactory();

I have checked in SQL profiler, and when I get a list of countrys for a user, the are loaded once, and I get cache hits after every other request. The nice thing is that when displaying the users country name, it loads from the cache, and does not make a request to the database. I got some tips from this posting by Gabriel Schenker. Hope that helps? If you found a better/proper way, please let me know? Thanks!