Share the first level cache between different sessions?

Is it possible that different NHibernate sessions will use the same Level 1 cache? I tried to implement it with interceptors and listeners. Everything works fine except for 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);
    }

}

      

+2


source to share


1 answer


No 1st level or session cache cannot be shared, if you want to use cache you have to use 2nd level cache that comes with the session factory - see docs



you have to be careful as the cache will not be invalidated if the data is changed outside of nhibernate sessions, for example via triggers or some other client - or another instance of your code running on a different machine.

+2


source







All Articles