Search code examples
nhibernatefluent-nhibernatenhibernate-mapping

Fluent nHibernate L2 Caching Not Working On HasMany Items


I’m wondering if I have mis-understood how the L2 caching works. I am trying to cache a ‘HasMany(x => x.Posts)’, Bascially I have a topic that has many posts under it - I was under the impression that if I added the following at the top of my topic map

Cache.ReadWrite().IncludeAll();

its caches map and hasManys until either the underlying data changes of app is restarted? I have my L2 cache configured like so

Fluently.Configure()
.Database(MsSqlConfiguration.MsSql2008.ConnectionString(c => c.FromConnectionStringWithKey("MyAppConString")))
.Cache(c => c.ProviderClass<SysCacheProvider>().UseQueryCache())
.Mappings(m => m.FluentMappings.AddFromAssemblyOf<MembershipUserMap>())
Etc…etc..

In my Topic map I have the following (I have removed a load of the normal maps to shorten it), and you can see the HasMany on the posts.

    public TopicMap()
    {
        Cache.ReadWrite().IncludeAll();

        Id(x => x.Id);
        Map(x => x.Name);
        *lots of other normal maps*

        References(x => x.Category).Column("Category_Id");
        References(x => x.User).Column("MembershipUser_Id");
        References(x => x.LastPost).Column("Post_Id").Nullable();

        HasMany(x => x.Posts)
            .Cascade.AllDeleteOrphan().KeyColumn("Topic_Id")
            .Inverse();

    *And a few other HasManys*
    }

So if I grab all topics, loop over and do the following

Topic.Posts.Count()

Using SqlProfiler I see the get all posts for each topic (First hit), but if I reload the page I still see all the gets posts for topic queries??

Am I missing something?? I thought this should be cached now??


Solution

  • Ayende has a good post explaining the same problem that you have run into.

    Basically, what you have there is caching only IDs of Posts, not the posts itself. Notice that you have enabled caching for Topic entities, but you probably didn't do the same for Post entities in PostMap.

    Add Cache.ReadWrite() to PostMap also.

    Notice that NHibernate won't be able to do the collection caching right in most of the cases if you are using eager loading with Fetch.Join(), like you have in your other question.

    Here's a very good overview of the caching and the problems you might have with eager loading collections.