Reputation: 7977
I have wrapped the NHibernate session in my own IDataContext. My NHibernate implementation of this is as follows:
public class NHibernateDataContext : IDataContext {
private readonly ISession _session;
public NHibernateDataContext(ISession session) {
_session = session;
Begin();
}
public IRepository<T> Repository<T>() where T : class {
return new NHibernateRepository<T>(_session);
}
public void Begin() {
if (!_session.Transaction.IsActive)
_session.BeginTransaction();
}
public void Commit() {
if (_session.Transaction.IsActive)
_session.Transaction.Commit();
}
public void Dispose() {
_session.Close();
}
}
public class NHibernateRepository<T> : IRepository<T> where T : class {
private readonly ISession _session;
public NHibernateRepository(ISession session) {
_session = session;
}
public IQueryable<T> GetAll() {
return _session.Query<T>();
}
public T GetByID(int id) {
return _session.Get<T>(id);
}
public void Insert(T entity) {
_session.SaveOrUpdate(entity);
}
public void Delete(T entity) {
_session.Delete(entity);
}
}
Using Microsoft Unity i then register this by saying:
// Configure the container
container.RegisterType<ISessionFactory>(new ContainerControlledLifetimeManager(), new InjectionFactory(c => {
return CreateSessionFactory();
}));
container.RegisterType<ISession>(new InjectionFactory(c => {
var sessionFactory = container.Resolve<ISessionFactory>();
return sessionFactory.OpenSession();
}));
container.RegisterType<IDataContext, NHibernateDataContext>(new PerRequestLifetimeManager<IDataContext>());
So far so good, but my application needs to produce some large reports. I have found that they get exponentially slower due to the 1st level cache bloating. I understand the IStatelessSession interface allows me to do this.
How can i refactor my application so that i can easily use the IStatelessSession instead ISession when querying some data? Please note that for every request i would still like to have an ISession open, but only an IStatelessSession when i need it.
I'd appreciate the help. Thanks
Upvotes: 2
Views: 1715
Reputation: 17350
IStatelessSession behavior is significantly different from ISession:
A stateless session does not implement a first-level cache nor interact with any second-level cache, nor does it implement transactional write-behind or automatic dirty checking, nor do operations cascade to associated instances. Collections are ignored by a stateless session. Operations performed via a stateless session bypass NHibernate's event model and interceptors. Stateless sessions are vulnerable to data aliasing effects, due to the lack of a first-level cache.
You can fight 1st level cache bloating by calling ISession.Clear
periodically, say every 500 loaded objects. Otherwise you can just create a new 'context' (but be prepared for unexpected behavior).
public class NHibernateStatelessDataContext : IDataContext {
private readonly IStatelessSession _session;
...
}
Upvotes: 3