NHibernate second-level caching - evicting regions
Asked Answered
C

2

6

We have a number of cache regions set up in our nHibernate implementation. In order to avoid trouble with load balanced web servers, I want to effectively disable the caching on the pages that edit the cached data. I can write a method that clears out all my query caches, my class caches and my entity caches easily enough.

But what I really want is to clear the cache by region. sessionFactory.EvictQueries() will take a region parameter, but Evict() and EvictCollection() does not. I don't really want to throw away the whole cache here, nor do I want to maintain some sort of clumsy dictionary associating types with their cache regions. Does nHibernate have a way to ask an entity or collection what its caching settings are?

thanks

Calculation answered 24/2, 2012 at 15:40 Comment(4)
Hey @Ted, it sounds like you're trying to do something manually that you can already wire up. Is there a reason that you are not setting up some kind of cache dependency to automatically evict items when a change is made to the data store? Like a SqlCacheDependency?Desma
or even better- use a distributed cache? nHibernate supports thoseVindicable
I'd love to use a distributed cache but the customers are not keen, for stupid customer reasons. I am looking into CacheDependency now, though we're using Oracle so the specific SQL Server implementation is no use to me. Looks like the generic implementation of dbCacheDependency works by polling, and relies on some OLEDB stuff. Is that performant? does it have implications for my driver choices? I'm looking at 3rd party Oracle drivers like DataDirect and Devart as well as ODP.NET.Calculation
So ,dbCacheDependency isn't an option for me either as we're fairly heavily restricted in terms of the database changes we can make at this point, and the Oracle implementation relies on a whole set of triggers and auxiliary tables to do its thing. The thing is, nHibernate nearly gives me the information I need - its easy to get hold of metadata for my entities and collections. All I need is to access the <cache region=...> tag within it.....Calculation
J
6

I've just done the same thing. For everyone's benefit, here is the method I constructed:

public void ClearCache(string regionName)
    {
        // Use your favourite IOC to get to the session factory
        var sessionFactory = ObjectFactory.GetInstance<ISessionFactory>();

        sessionFactory.EvictQueries(regionName);

        foreach (var collectionMetaData in sessionFactory.GetAllCollectionMetadata().Values)
        {
            var collectionPersister = collectionMetaData as NHibernate.Persister.Collection.ICollectionPersister;
            if (collectionPersister != null)
            {
                if ((collectionPersister.Cache != null) && (collectionPersister.Cache.RegionName == regionName))
                {
                    sessionFactory.EvictCollection(collectionPersister.Role);
                }
            }
        }

        foreach (var classMetaData in sessionFactory.GetAllClassMetadata().Values)
        {
            var entityPersister = classMetaData as NHibernate.Persister.Entity.IEntityPersister;
            if (entityPersister != null)
            {
                if ((entityPersister.Cache != null) && (entityPersister.Cache.RegionName == regionName))
                {
                    sessionFactory.EvictEntity(entityPersister.EntityName);
                }
            }
        }
    }
Jacks answered 18/6, 2012 at 6:40 Comment(0)
C
0

OK, looks like i've answered my own question. The default interface that's returned when you pull out the nHibernate metadata doesn't provide information on caching, however if you dig around in the implementations of it, it does. A bit clumsy, but it does the job.

Calculation answered 27/2, 2012 at 13:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.