Is it possible for different NHibernate sessions to share one 1st level cache? I`ve tried to implement it using interceptors and listeners. All works fine except Session.Evict().
public class SharedCache :
EmptyInterceptor,
IFlushEntityEventListener,
ILoadEventListener,
IEvictEventListener,
ISharedCache {
[ThreadStatic]
private readonly Dictionary<string, Dictionary<object, object>> cache;
private ISessionFactory factory;
public SharedCache() {
this.cache = new Dictionary<string, Dictionary<object, object>>();
}
public override object Instantiate(string clazz, EntityMode entityMode, object id) {
var entityCache = this.GetCache(clazz);
if (entityCache.ContainsKey(id))
return entityCache[id];
var entity = Activator.CreateInstance(Type.GetType(clazz));
this.factory.GetClassMetadata(clazz).SetIdentifier(entity, id, entityMode);
return entity;
}
private Dictionary<object, object> GetCache(string clazz) {
if (!cache.ContainsKey(clazz))
cache.Add(clazz, new Dictionary<object, object>());
return cache[clazz];
}
public void Configure(Configuration config) {
config.SetInterceptor(this);
config.SetListener(ListenerType.FlushEntity, this);
config.SetListener(ListenerType.Load, this);
config.SetListener(ListenerType.Evict, this);
}
public void Initialize(ISessionFactory sessionFactory) {
this.factory = sessionFactory;
}
public void OnFlushEntity(FlushEntityEvent ev) {
var entry = ev.EntityEntry;
var entityCache = this.GetCache(ev.EntityEntry.EntityName);
if (entry.Status == Status.Deleted) {
entityCache.Remove(entry.Id);
return;
}
if (!entry.ExistsInDatabase && !entityCache.ContainsKey(entry.Id))
entityCache.Add(entry.Id, ev.Entity);
}
public void OnLoad(LoadEvent ev, LoadType loadType) {
var entityCache = this.GetCache(ev.EntityClassName);
if (entityCache.ContainsKey(ev.EntityId))
ev.Result = entityCache[ev.EntityId];
}
public void OnEvict(EvictEvent ev) {
var entityName = ev.Session.GetEntityName(ev.Entity);
var entityCache = this.GetCache(entityName);
var id = ev.Session.GetIdentifier(ev.Entity);
entityCache.Remove(id);
}
}