Search code examples
asp.nethibernatenhibernatesecond-level-cache

Second level cache does not cache filtered collections in NHibernate?


I am configuring 2nd level cache with NHibernate 3.0. 2nd level cache works great for Entities and Collections but I also have some Entities which have filtered collections.

 <bag name="EntityTrans" cascade="all-delete-orphan" table="EntityTrans">
            <key column="entityId" not-null="true" />
            <one-to-many class="MyDomain.EntityTran, MyDomain" />
            <filter name="cultureFilter" condition=":cultureCode = CultureCode" />
        </bag>

NHibernate 2nd level caching does not cache the above filtered collection. I can see in NHProf that for filtered collection queries are sent to database. My NHibernate config file has the following entries.

<class-cache class="MyDomain.EntityTran, MuDomain" region="MyRegion" usage="read-only"/>
<collection-cache collection="MyDomain.Entity.EntityTrans" region="MyRegion" usage="read-only"/>

Do I need to add something more to cache the filtered collection?


Solution

  • Currently NHibernate doesn't support second level cache for filtered collections.

    First I found this forum post. Then I looked through the code(CollectionLoadContext.cs ~line 299) and found the following:

    if (!(session.EnabledFilters.Count == 0) && persister.IsAffectedByEnabledFilters(session))
    {
        // some filters affecting the collection are enabled on the session, so do not do the put into the cache.
        log.Debug("Refusing to add to cache due to enabled filters");
        // todo : add the notion of enabled filters to the CacheKey to differentiate filtered collections from non-filtered;
        //      but CacheKey is currently used for both collections and entities; would ideally need to define two separate ones;
        //      currently this works in conjunction with the check on
        //      DefaultInitializeCollectionEventHandler.initializeCollectionFromCache() (which makes sure to not read from
        //      cache with enabled filters).
        return; // EARLY EXIT!!!!!
    }