Pedro Santos
Pedro Santos

Reputation: 1004

NHibernate 2nd Level Cache issue with QueryOver

I have 2nd level cache working perfectly when I use Session.Get() however if I use the new QueryOver API in NH3.0 the cache does not get hit.

This works perfectly:

public TEntity Get(int id)
{
  return session.Get<TEntity>(id);
}

This does not hit the cache:

public TEntity Get(Expression<Func<TEntity bool>> filter)
{
    var query = _session.QueryOver<TEntity>()
                .Where(filter);

    query.Cacheable();     
    return query.SingleOrDefault();
}

I'm using transactions to make sure the 2nd level cache is used correctly.

Here is my Session configuration:

Session = Fluently.Configure()
                .Database(SQLiteConfiguration.Standard.InMemory().ShowSql())
                .Mappings(x => x.FluentMappings.AddFromAssemblyOf<Activity>())
                .Cache(c => c.UseSecondLevelCache()
                            .UseQueryCache()
                            .ProviderClass<NHibernate.Cache.HashtableCacheProvider>())
                .ExposeConfiguration(cfg => configuration = cfg)
                .BuildSessionFactory()
                .OpenSession();

I'm setting my entities for cache usage:

public class CommentMap : ClassMap<Comment>
    {
        public CommentMap()
        {
            Cache.ReadWrite();

            Id(x => x.Id);
            Map(x => x.Message);
            References(x => x.Activity);
            References(x => x.User);
        }
    }

I'm calling the Cacheable method on my QueryOver queries:

public TEntity Get(Expression<Func<TEntity, bool>> filter)
        {
            var query = _session.QueryOver<TEntity>()
                .Where(filter);

            query
                .Cacheable();

            return query.SingleOrDefault();
        }

I must be missing something, just can't figure out what.

Upvotes: 2

Views: 2885

Answers (1)

Diego Mijelshon
Diego Mijelshon

Reputation: 52745

There are several related issues:

  • Session.Load never hits the DB, so it's not a proof that caching is working
  • Query cache is enabled separately from entity cache
  • Query caching is explicit: you have to tell NHibernate to cache that QueryOver using the Cacheable() method

Also, make sure you have entity caching for the entities whose queries you'll be caching. Otherwise cache will make things worse.

Upvotes: 6

Related Questions