Everyone knows that there is a cache in the session. This cache can usually be cleared in two ways:
- Session.Evict
- Session.Clear
The second method removes the entire cache, not just for a single entry.
I have a business method. It gets the identifier of a large object (from an aspx site) or sometimes several identifiers. And do your own SQL operation in the database (using an SQL query with complex logic so as not to load all the data in C #). Then I need to invalidate the cache. Thus, any potential load of the object goes without a cache directly from the database.
Unfortunately, eviction only accepts objects. Also, its implementation of DefaultEvictEventListener has a clear separation in the code path - separate for proxies and non-proxied classes. I tried just creating an object, filling in the identifier manually and passing it to Evict. This will not work. Since I understand that Evict is not a proxied class, use GetHashCode to find and remove an object from the cache. Therefore, if I do not redefine this, it will not work. I have many native sql batch operations, so redefining all GetHashcode in all object objects will do a lot of work. Also, I'm not sure if this case removes proxies from the cache or not. Update: As far as I tried overriding GetHashCode for me, also did not help. StatefulPersistenceContext.RemoveEntry not found object because it uses RuntimeHelpers.GetHashCode. Therefore, this solution is not even possible.
Using NHibernate sources, I produced the following solution:
public static class NHSessionHelper: DefaultEvictEventListener public static void RemoveEntityFromCache(this ISession session, Type type, object entityId) { ISessionImplementor sessionImpl = session.GetSessionImplementation(); IPersistenceContext persistenceContext = sessionImpl.PersistenceContext; IEntityPersister persister = sessionImpl.Factory.GetEntityPersister(type.FullName); if (persister == null) { return; } EntityKey key = new EntityKey(entityId, persister, sessionImpl.EntityMode); persistenceContext.RemoveProxy(key); object entity = persistenceContext.RemoveEntity(key); if (entity != null) { EntityEntry e = persistenceContext.RemoveEntry(entity); DoEvict(entity, key, e.Persister, (IEventSource)sessionImpl); } }
It just uses part of the NHibenate implementation. But I'm not good at duplicating the code. Maybe someone has other ideas?
nhibernate
Yauhen.f
source share