I have a very simple asp.net-mvc CRUD site that uses nhibernate to interact with mySQL db. I use UnitOfWork and Repository templates. After upgrading to MVC 4 and the latest versions of nhibernate and mySQL (via nuget), I suddenly see a strange problem when updates and deletes stopped working.
Here is an example Remove code in my controller that stops working:
public ActionResult Delete(int id) { MyEvent c = _eventRepository.FindBy(id); _unitOfWork.Begin(); _eventRepository.Delete(c); _unitOfWork.End(); return RedirectToAction("Index"); }
where the UnitOfWork code is as follows:
public UnitOfWork(ISessionFactory sessionFactory) { _sessionFactory = sessionFactory; Session = _sessionFactory.OpenSession(); Session.FlushMode = FlushMode.Auto; } public void End() { Commit(); if (Session.IsOpen) { Session.Close(); } } public void Commit() { if (!_transaction.IsActive) { throw new InvalidOperationException("No active transation"); } _transaction.Commit(); } public void Begin() { _transaction = Session.BeginTransaction(IsolationLevel.ReadCommitted); }
I tested adding a new item that worked fine (a new row appears in the DB table), but when I test either Updates or Deletes, the code works fine (I don't get any exceptions in the code), but the fields arenβt updated when I Iβm doing an update, and the record is not deleted when the delete code is run.
So, to read, reading data from mySQL db works fine, adding works fine, but updates and deletes stopped working for all the tables (which used to work). I did a test doing plain SQL using Toad for MySQL, and it worked perfectly (using the same credentials that I use to connect in my code)
To debug a little more, I launched the nhibernate profiler, and this is what I see for a delete or update record:

and this is what I see when loading a regular reading page:

Not sure if this is useful for explaining the problem, but I decided that it would not hurt to add screenshots.
Any suggestions on what might happen. Could this be a legal issue (compared to some software library bug?). Again, as mentioned above, this code previously definitely worked.
Here is my Ninject Ioc code:
string connectionString = ConfigurationManager.ConnectionStrings["LocalMySqlServer"].ConnectionString; var helper = new NHibernateHelper(connectionString); Bind<ISessionFactory>().ToConstant(helper.SessionFactory) .InSingletonScope(); Bind<IUnitOfWork>().To<UnitOfWork>(); var sessionProvider = new SessionProvider(); Bind<ISession>().ToProvider(sessionProvider); var unitOfWork = new UnitOfWork(helper.SessionFactory); Bind(typeof(IIntKeyedRepository<>)).To(typeof(Repository<>)); }
and here is my unitofwork.cs code:
public class UnitOfWork : IUnitOfWork { private readonly ISessionFactory _sessionFactory; private ITransaction _transaction; public ISession Session { get; private set; } public UnitOfWork(ISessionFactory sessionFactory) { _sessionFactory = sessionFactory; Session = _sessionFactory.OpenSession(); Session.FlushMode = FlushMode.Auto; } public void End() { Commit(); if (Session.IsOpen) { Session.Close(); } } public void Begin() { _transaction = Session.BeginTransaction(IsolationLevel.ReadCommitted); } public void Dispose() { if (Session.IsOpen) { Session.Close(); } } public void Commit() { if (!_transaction.IsActive) { throw new InvalidOperationException("No active transation"); } _transaction.Commit(); } public void Rollback() { if (_transaction.IsActive) { _transaction.Rollback(); } } }
and here is my repository code:
public class Repository<T> : IIntKeyedRepository<T> where T : class { private readonly ISession _session; private ITransaction _trans; public T FindBy(int id) { return _session.Get<T>(id); } public Repository(ISession session) { _session = session; } public bool Add(T entity) { _session.Save(entity); return true; } public bool Add(IEnumerable<T> items) { foreach (T item in items) { _session.Save(item); } return true; } public bool Update(T entity) { _session.Update(entity); return true; } public bool Delete(T entity) { _session.Delete(entity); return true; } public bool Delete(IEnumerable<T> entities) { foreach (T entity in entities) { _session.Delete(entity); } return true; } #endregion #region IIntKeyedRepository<T> Members public T FindBy(int id) { return _session.Get<T>(id); } #endregion #region IReadOnlyRepository<T> Members public IQueryable<T> All() { return _session.Query<T>(); } public T FindBy(Expression<Func<T, bool>> expression) { return FilterBy(expression).Single(); } public IQueryable<T> FilterBy(Expression<Func<T, bool>> expression) { return All().Where(expression).AsQueryable(); } }