12
votes

I'm trying to understand how to configure Fluent NHibernate to enable 2nd-level caching for queries, entities, etc... And at the same time use automapping. There is very little information online on how to do that. Sure it can be done when mapping the classes one by one... But how about automapping?

Here is my configuration code so far:

AutoPersistenceModel model = AutoMap.AssemblyOf<Seminar>()
.Where(t => t.Namespace == "[MY NAMESPACE]")
.Conventions.Add(DefaultCascade.All());

Configuration config = Fluently.Configure()
.Database
(
    MsSqlConfiguration.MsSql2005
    .ConnectionString(@"[MY CONNECTION STRING]")
)
.Mappings(m => m.AutoMappings.Add(model))
.BuildConfiguration();

_sessionFactory = config.BuildSessionFactory();

Thanks!

2

2 Answers

7
votes

Assuming you've already downloaded a 2nd-level cache provider from the NHibernate Contribution project, you should be able to use the following to initialize the cache within your automappings setup.

Configuration config = Fluently.Configure()
.Database
(
    MsSqlConfiguration.MsSql2005
    .ConnectionString(@"[MY CONNECTION STRING]")
    .Cache(c => c.UseQueryCache().ProviderClass<YourCacheProviderOfChoice>())
)
.Mappings(m => m.AutoMappings.Add(model))
.BuildConfiguration();

Selecting the queries you want to cache is simply a matter of calling SetCacheable(true) on your Criteria instance.

 var query = session.CreateQuery("from Blog b where b.Author = :author")
    .SetString("author", "Gabriel")
    .SetCacheable(true);
 var list = query.List<Blog>();

This is an epic blog post on NHibernate's first and second level caches, good reference material.

1
votes

I've been struggling with this for a while and was surprised how little information is out there. This question is the best I could find and even here the accepted answer doesn't say how to enable entity caching. Here's what I've found out.

To enable second level cache:

Fluently.Configure()
    .Database(/* your DB config */)
    .Cache(c => c.UseSecondLevelCache().ProviderClass<CacheProviderClass>())

You can use both this and query cache:

Fluently.Configure()
    .Database(/* your DB config */)
    .Cache(c => c.UseSecondLevelCache()
        .UseQueryCache()
        .ProviderClass<CacheProviderClass>())

To enable per-entity caching:

.Mappings(m => m.AutoMappings.Add(AutoMap.AssemblyOf<Entity>()
              .Conventions.Add(ConventionBuilder.Class.Always(c => c.Cache.ReadWrite()))
          )
)

Of course, you can use ReadOnly() or NonStrictReadWrite() if you wish.