The Inquisitive Coder – Davy Brion's Blog

Trying to walk that thin line between intelligence and ignorance

Archive for the 'NHibernate' Category

Avoiding Leaking Connections With NHibernate And TransactionScope

Posted by Davy Brion on 6th May 2010

One of the applications we’re currently working on wasn’t responding anymore on the development server.  The logfile showed the following message:

System.InvalidOperationException: Timeout expired.  The timeout period elapsed prior to obtaining a connection from the pool.  This may have occurred because all pooled connections were in use and max pool size was reached.

We’ve been using NHibernate in almost all of our projects for about 2 years now and we’ve never had this issue before.  The thing is though, we never used System.Transactions’ TransactionScope class before and always used NHibernate’s transactions directly.  In this project, we’re using TransactionScope for the first time (mostly because we need distributed transactions occasionally) so i immediately suspected that we were either doing something wrong with it, or that there was a bug somewhere.

After a while i managed to reproduce the problem with the following simple test fixture:

    [TestFixture]

    public class ConnectionLeakTest

    {

        private static ISessionFactory sessionFactory;

 

        static ConnectionLeakTest()

        {

            sessionFactory = new Configuration()

                .Configure()

                .AddAssembly("MyAssembly")

                .BuildSessionFactory();

        }

 

        [Test]

        public void LeaksConnection()

        {

            var counter = 11;

            for (int i = 0; i < counter; i++)

            {

                using (var scope = new TransactionScope(TransactionScopeOption.Required))

                {

                    using (var session = sessionFactory.OpenSession())

                    {

                        var blah = session.CreateCriteria<User>().List<User>();

                    }

                }

            }

        }

    }

 

If you assign counter a value that is greater than your ‘Max Pool Size’ value of your connection string, then you will get the following exception once you’re going through the loop for the ‘Max Pool Size’ + 1 time:

System.InvalidOperationException : Timeout expired.  The timeout period elapsed prior to obtaining a connection from the pool.  This may have occurred because all pooled connections were in use and max pool size was reached.

Bingo!

In normal situations, you would obviously call the Complete method of the TransactionScope instance before it is disposed to commit the current database transaction.  But in a situation where you can’t call the Complete method (as in: when an exception has occurred and you want to rollback the transaction), your database connection will actually leak until you’ve used up all of the connections in your connection pool. 

So the question is: How can we use a TransactionScope with NHibernate without leaking connections when we throw an exception (which should result in an automatic rollback of the current transaction)? 

I was always under the impression that merely opening an NHibernate session within a transaction scope was actually OK and that the session’s connection would make use of the current ambient transaction (the one created by the outer TransactionScope).  Pretty much every session-related action you perform in NHibernate results in calling the CheckAndUpdateSessionStatus method of the SessionImpl class, which in turn calls the EnlistInAmbientTransactionIfNeeded method.  That (as you can probably guess) will automatically enlist the current NHibernate session in the ambient transaction, which is the one that was created by the TransactionScope.  So, as i understand it, it should indeed be sufficient to open an NHibernate session within a TransactionScope to have every action performed by that session being enlisted in the current ambient transaction.   And it actually behaves as transactional as you’d expect it to be.  Your transaction is properly committed if you call the Complete method of the TransactionScope and it is indeed rolled back if you do not call the Complete method.  The only problem (and it’s a major one obviously) is that you’re connection will leak when the transaction is rolled back. 

Interestingly enough, if we change the test code to this:

        [Test]

        public void LeaksConnection()

        {

            var counter = 11;

            for (int i = 0; i < counter; i++)

            {

                using (var scope = new TransactionScope(TransactionScopeOption.Required))

                {

                    using (var session = sessionFactory.OpenSession())

                    using (var transaction = session.BeginTransaction())

                    {

                        var blah = session.CreateCriteria<User>().List<User>();

                        transaction.Rollback();

                    }

                }

            }

        }

 

Then the problem goes away.  Transactions are correctly rolled back, and none of the connections leak anymore.  It’s too bad that we still need to use NHibernate’s transactions only for the sake of being able to rollback in case of failure without leaking the connection, because again, when you’re not using an NHibernate transaction but are within a TransactionScope, your Session’s connection will indeed be enlisted in the transaction being governed by the TransactionScope.  So there certainly appears to be some kind of bug in NHibernate when it comes to cleaning up the connection of a session that has been enlisted in a TransactionScope’s transaction which is rolled back instead of committed.

Now, since i frequently see people on the intarweb showing examples of using an NHibernate session together with a TransactionScope yet without using an NHibernate transaction, i’d might as well post the way that i believe is the safest, and that shouldn’t leak any connections.

            using (var scope = new TransactionScope(TransactionScopeOption.Required))

            {

                using (var session = sessionFactory.OpenSession())

                using (var transaction = session.BeginTransaction())

                {

                    // do what you need to do with the session

                    transaction.Commit();

                }

                scope.Complete();

            }

 

If you need to rollback, simply throw an exception within the using block of the NHibernate transaction (before the transaction.Commit() call obviously) and everything takes care of itself.

Posted in MSDTC, NHibernate | 20 Comments »

MSDTC Woes With NServiceBus And NHibernate

Posted by Davy Brion on 19th March 2010

I’ve spent about 3 days trying to get something working that should’ve just worked.  I basically wanted some .NET code to use a distributed transaction to update some data in a database, and then publish a message on the service bus.  I want to do this in a distributed transaction because if something goes wrong, i want to roll back both transactions (the database change and the published message).  Normally, this should just work if you have MS DTC configured correctly.  On my machine, i enabled Network DTC Access, and allowed outbound transaction communication.  On the database server, Network DTC Access was already enabled and both outbound and inbound communication was allowed. 

Now the thing is, i’d either expect DTC to fail outright or to just work.  But it shouldn’t fail in one situation, and work in another.  On my machine, it failed in the following situation (which i’ll further refer to as Situation A):

  1. open a transaction scope
  2. open an nhibernate session
  3. hit the db
  4. publish a message through nservicebus
  5. close the nhibernate session
  6. complete and close the transaction scope

Step 4 and 5 could be switched around but it didn’t make a difference.  In Situation A, i always got a TransactionManagerCommunicationException with the following message:

Network access for Distributed Transaction Manager (MSDTC) has been disabled. Please enable DTC for network access in the security configuration for MSDTC using the Component Services Administrative tool.

Everyone who’s worked with MSDTC before probably knows that exception since it usually takes some fiddling with the settings to make things work.  The thing is, i was pretty sure that my settings, as well as the ones on the database server were correct.  Unfortunately, DTCPing didn’t confirm that since that too failed.

However, i also tried the following sequence of events (Situation B):

  1. open a transaction scope
  2. open an nhibernate session
  3. publish a message
  4. hit the db
  5. close the nhibernate session
  6. complete and close the transaction scope

And guess what.  That actually worked.  With full DTC transaction semantics.  The DTC statistics on the server confirmed that it was indeed using a DTC transaction, and if i made the code fail with an exception both the database action and the published message were correctly rolled back.

So the question is: why on earth does it only work when i publish a message before i hit the db?

During my investigation i noticed that in Situation A, the internal transaction that the transaction scope was using was a SqlDelegatedTransaction.  Which, if i’m not mistaken is an LTM transaction.  When trying to send a message to a message queue, the transaction manager tries to promote the current transaction to an OletxCommittableTransaction since the OleTx transaction protocol is required when using MSMQ (it doesn’t support LTM transactions).  For some reason, promoting the SqlDelegatedTransaction to a full DTC (OleTx) transaction fails on my machine.

In Situation B, the internal transaction is promoted to an OletxCommittableTransaction as soon as you try to send the message to a message queue.  Once it’s time to hit the DB, NHibernate nicely works together with the OletxCommittableTransaction and everything just works.

Now, i have no idea on earth why promotion of a SqlDelegatedTransaction fails, but after a long number of attempts and experiments to get it working correctly, i sorta gave up and figured i’d have to resort to a hack.  What i basically needed was for the transaction scope’s internal transaction to automatically be promoted to an OletxCommittableTransaction before i’d hit the database and without having to publish a dummy message at the beginning of the transaction.

I found one way of doing this which, while being a huge hack, is still relatively clean i think.  I wrote the following class:

    public class DummyEnlistmentNotification : IEnlistmentNotification

    {

        public static readonly Guid Id = new Guid("E2D35055-4187-4ff5-82A1-F1F161A008D0");

 

        public void Prepare(PreparingEnlistment preparingEnlistment)

        {

            preparingEnlistment.Prepared();

        }

 

        public void Commit(Enlistment enlistment)

        {

            enlistment.Done();

        }

 

        public void Rollback(Enlistment enlistment)

        {

            enlistment.Done();

        }

 

        public void InDoubt(Enlistment enlistment)

        {

            enlistment.Done();

        }

    }

 

Then, right after opening the transaction scope and before doing anything else, i do this:

    Transaction.Current.EnlistDurable(DummyEnlistmentNotification.Id, new DummyEnlistmentNotification(), EnlistmentOptions.None);

 

This basically tells the System.Transactions infrastructure that we’re adding our own Resource Manager to the current transaction.  And because it’s a durable Resource Manager, it now automatically promotes the internal transaction to an OletxCommittableTransaction and everything just works.  While our Resource Manager participates in the 2-phase-commit process, it doesn’t actually do anything.  It’s sole purpose is to force the creation of an OletxCommittableTransaction.

Like i said, it’s a hack but it’s still relatively clean.  I still have no idea why i needed to resort to this hack though… If anyone can shed some light on this, i’d highly appreciate it :)

Also, if you ever want to learn more about transactions in .NET or distributed transactions in particular, you really need to check out this article.  Without it, i probably wouldn’t have figured out what to do :)

Posted in .NET bugs, MSDTC, NHibernate, nservicebus | 13 Comments »

Using NHibernate In Your Service Layer

Posted by Davy Brion on 11th December 2009

I have an old post where i discuss how you can manage your NHibernate sessions in a service layer scenario.  Now, the example of the service layer code in that post was pretty poor and people were asking for a better example.  Hopefully, this post will do a better job at making sure everything is clear :)

First of all, the idea is to make sure that managing the NHibernate session (creating it, starting a transaction, committing or rolling back the transaction and closing the session) is taken care of automatically so you no longer have to worry about it.  I also want to avoid passing the NHibernate session around all the time.  This means that it will be created automatically when a request is sent to your service layer and stored in some place that will keep the instance alive during the handling of the service layer request.  Every class that needs a reference to the current session (ideally only classes that deal purely with data access) will be able to retrieve it very easily, all in a thread-safe manner that can never be influenced by other concurrent requests.

First of all, you need something to wrap NHibernate’s ISessionFactory.  I use the ISessionProvider for that:

    public interface ISessionProvider

    {

        ISession Create();

    }

 

    public class SessionProvider : ISessionProvider

    {

        private readonly ISessionFactory sessionFactory;

 

        public SessionProvider(string mappingAssemblyName)

        {

            Configuration configuration = new Configuration()

                .Configure()

                .AddAssembly(mappingAssemblyName);

 

            sessionFactory = configuration.BuildSessionFactory();

        }

 

        public ISession Create()

        {

            return sessionFactory.OpenSession();

        }

    }

 

In my case, i configure the IOC container to pass the name of the assembly that contains the mappings to the constructor of the SessionProvider class.  If you’re using this code directly in your application, you could just as well hardcode the name of the assembly here.

You’ll also need something that allows you to store and retrieve the NHibernate session for the duration of the current request.  I use the IActiveSessionManager for that:

    public interface IActiveSessionManager

    {

        ISession GetActiveSession();

        void SetActiveSession(ISession session);

        void ClearActiveSession();

        bool HasActiveSession { get; }

    }

 

    public class ActiveSessionManager : IActiveSessionManager

    {

        private const string sessionKey = "_currentSession";

        private readonly IRequestState requestState;

 

        public ActiveSessionManager(IRequestState requestState)

        {

            this.requestState = requestState;

        }

 

        public ISession GetActiveSession()

        {

            if (Current == null)

            {

                throw new InvalidOperationException("There is no active ISession instance for this thread");

            }

 

            return Current;

        }

 

        public void SetActiveSession(ISession session)

        {

            if (Current != null)

            {

                throw new InvalidOperationException("There is already an active ISession instance for this thread");

            }

 

            Current = session;

        }

 

        public void ClearActiveSession()

        {

            Current = null;

        }

 

        public bool HasActiveSession

        {

            get { return Current != null; }

        }

 

        protected virtual ISession Current

        {

            get

            {

                return requestState.Get<ISession>(sessionKey);

            }

            set

            {

                requestState.Store(sessionKey, value);

            }

        }

    }

 

This class will store the ISession instance in the current request state (definitely click on that link if you don’t know IRequestState yet).

Now we can create our own Unit Of Work.  This is not a pure Unit Of Work because it doesn’t do any change tracking or anything like that, but it does take care of creating an NHibernate session (which does do change tracking and anything that a real Unit Of Work should do) and cleaning it up when the Unit Of Work is completed.  Here’s my implementation:

    public interface IUnitOfWork : IDisposable

    {

        void Clear();

        void Flush();

        ITransaction CreateTransaction();

        ITransaction CreateTransaction(IsolationLevel isolationLevel);

    }

 

    public class UnitOfWork : Disposable, IUnitOfWork

    {

        private readonly IActiveSessionManager sessionManager;

        private readonly ISession session;

        private readonly bool isRootUnitOfWork;

 

        public UnitOfWork(ISessionProvider sessionProvider, IActiveSessionManager sessionManager)

        {

            this.sessionManager = sessionManager;

 

            if (sessionManager.HasActiveSession)

            {

                isRootUnitOfWork = false;

                session = sessionManager.GetActiveSession();

            }

            else

            {

                isRootUnitOfWork = true;

                session = sessionProvider.Create();

                sessionManager.SetActiveSession(session);

            }

        }

 

        public void Clear()

        {

            session.Clear();

        }

 

        public void Flush()

        {

            session.Flush();

        }

 

        public ITransaction CreateTransaction()

        {

            return CreateTransaction(IsolationLevel.ReadCommitted);

        }

 

        public ITransaction CreateTransaction(IsolationLevel isolationLevel)

        {

            if (session.Transaction != null && session.Transaction.IsActive)

            {

                throw new InvalidOperationException("nested transactions are not supported!");

            }

 

            return session.BeginTransaction(isolationLevel);

        }

 

        protected override void DisposeManagedResources()

        {

            if (isRootUnitOfWork)

            {

                if (session != null)

                {

                    session.Close();

                    session.Dispose();

                }

 

                sessionManager.ClearActiveSession();

            }

        }

    }

 

The idea is very simple.  When the Unit Of Work is created, it asks the IActiveSessionManager if there is already an active session available.  If not, it will create a new session through the ISessionProvider, and store it as the active session through the IActiveSessionManager.  In the old implementation, the Unit Of Work would automatically create a new session in the constructor, but this obviously causes problems if you want to reuse a certain request handler from another request handler if they both depend on a IUnitOfWork instance.   The IUnitOfWork interface doesn’t expose a lot of functionality but it’s all you need to manage your session in your service layer.  It gives you the ability to create a transaction, clear the session and flush the session.  When the IUnitOfWork is disposed, it will clean up the session and instruct the IActiveSessionManager to get rid of the session for this request. 

Once you have this, you have all you need to prepare your service layer to take care of NHibernate session management automatically.  I’m going to base the following service layer code example on Agatha (just because i think it’s the easiest way to implement a service layer ;) ) but you can do exactly the same in your service layer.  The important part is that you should configure your IOC container to inject a new instance of IUnitOfWork into the class that handles your service request.  When the container injects the new instance, the NHibernate session will be created and stored in the IActiveSessionManager so there’s no more reason why you would have to do this yourself.

Now, i use the following class as the base class for all my request handlers that need NHibernate support:

    public abstract class NhRequestHandler<TRequest, TResponse> : RequestHandler<TRequest, TResponse>

        where TRequest : Request

        where TResponse : Response

    {

        public IUnitOfWork UnitOfWork { get; set; }

 

        protected override void DisposeManagedResources()

        {

            if (UnitOfWork != null) UnitOfWork.Dispose();

        }

 

        public override Response Handle(Request request)

        {

            using (ITransaction transaction = UnitOfWork.CreateTransaction())

            {

                Response response;

 

                try

                {

                    response = base.Handle(request);

                    transaction.Commit();

                }

                catch (Exception handlerException)

                {

                    transaction.Rollback();

                    throw;

                }

 

                return response;

            }

        }

    }

 

(Note: the real implementation contains a bit more logging but other than that this is the real thing)

If you don’t understand the whole request handling concept, please check out the first 3 posts in this series.  Regardless of whether you’re using Agatha, your own Request/Response Service Layer or a classic (dare i say old-school?) service layer, the idea should be the same.  Make sure this code is centralized in one place so you don’t have to repeat yourself all over your service layer code.   Btw, in this case the IUnitOfWork instance is injected by the IOC container through Setter Injection instead of Constructor Injection.  I’ve already discussed the reasons on why i prefer Setter Injection in this case here.

Now, you’re going to have some classes that will need to use an ISession instance to perform their tasks.  I always create Repository classes for that, but the following approach would be similar for any other type of class which needs an ISession.   Call them Data Access Objects, Data Access Classes or Sloppy Joes for all i care.   Whatever you call these classes, they need a dependency on the IActiveSessionManager.   Simply declare the IActiveSessionManager to be a dependency of your Sloppy Joe, i mean, Repository or DAO or whatever, like this:

    public class Repository<T> : IRepository<T>

    {

        private readonly IActiveSessionManager activeSessionManager;

 

        public Repository(IActiveSessionManager activeSessionManager)

        {

            this.activeSessionManager = activeSessionManager;

        }

 

        protected ISession Session

        {

            get { return activeSessionManager.GetActiveSession(); }

        }

 

Now you can write request handlers like this:

    public class GetCustomersRequestHandler : NhRequestHandler<GetCustomersRequest, GetCustomersResponse>

    {

        private readonly IRepository<Customer> repository;

 

        public GetCustomersRequestHandler(IRepository<Customer> repository)

        {

            this.repository = repository;

        }

 

        public override Response Handle(GetCustomersRequest request)

        {

            var response = CreateTypedResponse();

            response.Customers = ConvertToDtos(repository.FindAll(request.Criteria));

            return response;

        }

 

        private CustomerDto[] ConvertToDtos(IEnumerable<Customer> customers)

        {

            // …

        }

    }

 

Obviously, this is a simple example but it works just as well for complex request handlers.  Your NHibernate session is created and cleaned up automatically, without you having to write that code every single time. Each request handler will run in a transaction, and it will be committed or rolled back automatically without you having to do anything for it.  And you only need to access the ISession instance in your Sloppy Joes.

Also keep in mind that you can also use the the ISessionProvider, IActiveSessionManager and IUnitOfWork in a purely web-based scenario as well if you want to.

Posted in NHibernate | 27 Comments »

Testing CRUD Operations With NHibernate

Posted by Davy Brion on 7th December 2009

I was asked to show how you can easily do CRUD tests, so here’s a base class that makes it very easy

    public abstract class CrudTest<TEntity, TId> : NHibernateTest

        where TEntity : IHaveAnId<TId>

    {

        [Test]

        public virtual void SelectQueryWorks()

        {

            session.CreateCriteria(typeof(TEntity)).SetMaxResults(5).List();

        }

 

        [Test]

        public virtual void AddEntity_EntityWasAdded()

        {

            var entity = BuildEntity();

 

            InsertEntity(entity);

 

            session.Evict(entity);

 

            var reloadedEntity = session.Get<TEntity>(entity.Id);

 

            Assert.IsNotNull(reloadedEntity);

            AssertAreEqual(entity, reloadedEntity);

            AssertValidId(reloadedEntity);

        }

 

        [Test]

        public virtual void UpdateEntity_EntityWasUpdated()

        {

            var entity = BuildEntity();

 

            InsertEntity(entity);

            ModifyEntity(entity);

            UpdateEntity(entity);

 

            session.Evict(entity);

 

            var reloadedEntity = session.Get<TEntity>(entity.Id);

            Assert.IsNotNull(reloadedEntity);

            AssertAreEqual(entity, reloadedEntity);

        }

 

        [Test]

        public virtual void DeleteEntity_EntityWasDeleted()

        {

            var entity = BuildEntity();

 

            InsertEntity(entity);

            DeleteEntity(entity);

 

            Assert.IsNull(session.Get<TEntity>(entity.Id));

        }

 

        protected virtual void InsertEntity(TEntity entity)

        {

            session.Save(entity);

            session.Flush();

        }

 

        protected virtual void UpdateEntity(TEntity entity)

        {

            session.Update(entity);

            session.Flush();

        }

 

        protected virtual void DeleteEntity(TEntity entity)

        {

            session.Delete(entity);

            session.Flush();

        }

 

        protected abstract TEntity BuildEntity();

        protected abstract void ModifyEntity(TEntity entity);

        protected abstract void AssertAreEqual(TEntity expectedEntity, TEntity actualEntity);

        protected abstract void AssertValidId(TEntity entity);

    }

 

Simply inherit from this class, implement the BuildEntity, ModifyEntity, AssertAreEqual and AssertValidId methods and that’s it.  Those methods are usually pretty simple.  In BuildEntity you just create an unpersisted entity and assign values to the properties, in ModifyEntity you modify the properties, and in AssertAreEqual you compare the properties of both instances.  In AssertValidId, you make sure that the ID value is ok (depending on your identifier strategy).

This is good for regular CRUD operations, though we typically add extra tests when we want to test cascades or one-to-many associations mapped with inverse=”true”.

Posted in NHibernate, Test Driven Development | 13 Comments »

Unit Testing An NHibernate Application

Posted by Davy Brion on 6th December 2009

Grant Palin recently asked me for an in-depth article on TDD’ing an NHibernate application. While this post won’t be very in-depth, it might be helpful already.  There are basically two approaches that i’ve seen used with good results, though there are obviously more approaches that you can use.  I’m going to limit the scope of this post to the following two approaches though, and i’ll also discuss exactly what we test.

Creating a new database for each test (or testfixture)

This approach creates the database at the beginning of each test (or testfixture), runs the test (or tests in the fixture), and then destroys the database after the test (or testfixture) completed.  The easiest way to do this is to create a base test class that all of you data access test class should inherit from.  Here’s a simple example:

    public class NHibernateTest

    {

        private Configuration configuration;

        protected ISessionFactory sessionFactory;

 

        [TestFixtureSetUp]

        public void TestFixtureSetup()

        {

            configuration = new Configuration()

                .Configure()

                .AddAssembly("YourAssemblyName");

 

            new SchemaExport(configuration).Create(false, true);

            sessionFactory = configuration.BuildSessionFactory();

        }

 

        [TestFixtureTearDown]

        public void TestFixtureTearDown()

        {

            new SchemaExport(configuration).Drop(false, true);

        }

 

        protected ISession CreateTransactionalSession()

        {

            var session = sessionFactory.OpenSession();

            session.BeginTransaction();

            return session;

        }

    }

 

This class will create the database from scratch once for each TestFixture, which means that each test in the fixture will use the same database.  It also destroys the database at the end of the fixture.  It creates the database based on your mappings, and as you can see, you really don’t have to do a lot for this.  If you want the database to be recreated and dropped for each test, then you obviously need to move the code in the TestFixtureSetup and TestFixtureTearDown methods to your regular SetUp and TearDown methods.  If you go that route, i’d advise you to include empty template methods before and after the setup and teardown so you can plug in some extra code before and after these operations in your derived test classes.

The biggest benefit of this approach is that you don’t have any possibly present state in the database that can influence your tests.  The downside is that you can’t rely on certain data (eg reference data) to be present and you have to recreate it whenever you need it.   You can also use multiple transactions in your tests, though you are also responsible for cleaning any data that is left in the database at the end of each test.  You also need to guarantee that this always happens because any data that is left by one test might influence another one.   Also, if you leave data in the database, that might lead to problems when dropping the database, so you really need to be careful with this.

Another problem with this example is that there is no automatic way to push the ISession instance to your data access components.  That could easily be added though, depending on how your data access components retrieve a reference to a valid ISession.

Tests that automatically roll back their transactions

This is the approach that we always use at work.  These tests require your database to be set up in a valid manner before your tests begin.  Each test uses one transaction, which is automatically rolled back at the end of the test to prevent the possibility of any test data remaining in the database.   With this way of testing, it’s also possible to provide some kind of ‘known state’ in the database (eg reference data) that you can use from within your code.

Here’s the NHibernateTest class that our NHibernate test classes all inherit from:

    public abstract class NHibernateTest

    {

        protected static readonly ActiveSessionManager activeSessionManager = new ActiveSessionManager();

 

        private UnitOfWork unitOfWork;

        protected ISession session;

 

        protected abstract ISessionProvider GetSessionProvider();

 

        protected virtual IActiveSessionManager GetActiveSessionManager()

        {

            return activeSessionManager;

        }

 

        [SetUp]

        public void SetUp()

        {

            BeforeSetup();

            var sessionManager = GetActiveSessionManager();

            unitOfWork = new UnitOfWork(GetSessionProvider(), sessionManager);

            session = sessionManager.GetActiveSession();

            unitOfWork.CreateTransaction();

            AfterSetup();

        }

 

        [TearDown]

        public void TearDown()

        {

            BeforeTearDown();

 

            if (unitOfWork != null)

            {

                unitOfWork.Dispose();

            }

 

            unitOfWork = null;

            AfterTearDown();

        }

 

        protected virtual void BeforeSetup() { }

        protected virtual void AfterSetup() { }

        protected virtual void BeforeTearDown() { }

        protected virtual void AfterTearDown() { }

    }

 

Now, this example uses our UnitOfWork and ActiveSessionManager classes (read this if you haven’t seen those yet) to make sure that our data access components can access the current ISession instance.  Each test has a valid ISession present, which has already created a transaction and we can create/modify/delete data, run our queries, modify some stuff again, run our queries again and perform our assertions, all in the same transaction.  After the test is completed, the transaction is never committed (and thus, automatically rolled back) so none of that data ever remains in the database.

What Exactly Do We Test?

Well, we test everything basically.  We test all of our CRUD operations (again, with a simple base class which only requires you to implement the BuildEntity, ModifyEntity and AssertEqual methods and does all of the operations and checks automatically) for each entity.  That’s right, for each entity.  The extra work that this requires really doesn’t take a lot of time and it lets us know for a fact that our mappings are valid.

We also test every custom query that we write, always using the following approach: create some test data, flush the session, perform your query and verify that the expected data has indeed been returned by the query, and also that data that shouldn’t have been returned isn’t there.

And that’s pretty much it.  We mock the data layer in all of our other tests, so our CRUD and query tests are the only ones that actually use NHibernate and the database.  But CRUD actions and queries are tested very extensively.

Posted in NHibernate, Test Driven Development | 11 Comments »

Why NHibernate Entities Need A Public Or Protected Parameterless Constructor

Posted by Davy Brion on 4th October 2009

I have an older post where i discuss how you can implement a Value Object with NHibernate. In that post i mentioned the following:

NHibernate allows a private default constructor for Value Objects, but for Entities you will need a default public or protected constructor as private is not sufficient.

I got the following comment from someone:

I too am trying to determine how well NHibernate lives up to the promise of persistence ignorance. I can definitely live with unnecessary private constructors, but I’m dubious about adding protected constructors just to support an ORM.

At any rate, I was surprised by the sentence I quoted, because I didn’t realize there were any circumstances in which NHibernate required protected default constructors.

Once again, the answer is related to the dynamic proxies that NHibernate uses. Value Objects will never be proxied by NHibernate, so NHibernate only needs a private default constructor to create the instances. If an entity is eligible for lazy loading however, then NHibernate will create a type which inherits from your entity (this is described in depth here and here). Which means that we really need either a public or protected constructor in entity classes that are eligible for lazy loading. Consider the following class:

    public class SomeEntity

    {

        public SomeEntity(string someRequiredValue)

        {

        }

 

        private SomeEntity()

        {

        }

    }

If we try to create the following derived class:

    public class SomeEntityProxy : SomeEntity

    {

    }

We get the following compiler error:

Error 1 ‘ConsoleApplication1.SomeEntity.SomeEntity()’ is inaccessible due to its protection level

It’s a silly example, but it does show why entity types need at least a public or a protected default constructor and why a private one isn’t sufficient.

Posted in NHibernate | 4 Comments »

Must Everything Be Virtual With NHibernate, Part III

Posted by Davy Brion on 27th September 2009

In the previous post i showed a piece of code which suffers from 2 problems and asked you guys to spot both problems. One of the problems was pointed out in the comments, but nobody mentioned the other one.

Once again, this is the code example:

transitive_persistence41

Instead of making everything virtual, only properties that are eligible for lazy-loading have been made virtual. Now, the line of code that is problematic is obviously the one where the DiscountPercentage of the customer backing field is accessed. I will address using the field instead of the property later on in this post so bear with me for now.

There are 2 situations in which this code will fail badly. The first situation is when you’re dealing with a proxy of an Order. If you have an uninitialized proxy of Order, and you call the non-virtual CreateOrderLine method then you will get a NullReferenceException because the proxy can’t intercept the call to CreateOrderLine, and because it also can’t intercept accessing the customer field, which will be null at that time. This problem was correctly spotted by one of the people who left a comment.

The other problem is far worse, IMO. Suppose you have a genuine instance of an Order object, but its reference properties haven’t been loaded yet and are uninitialized proxies. If there is no requirement for every public member of a proxy-able type to be virtual, then we can pretty much assume that the DiscountPercentage of the Customer class is also non-virtual. Which means that with this code, we have no possible way of intercepting the call to the Customer’s proxy’s DiscountPercentage property. Unfortunately, DiscountPercentage will have its default value of 0, so you won’t get an exception… instead, the customer gets no discount even though its record in the database might have a discount set.

The possibility of running into one of these problems due to usage of an ORM and depending on how an object is loaded is simply unacceptable. Some people commented on the usage of the customer backing field instead of the Customer property with a “then simply don’t do that” response. That’s not an acceptable solution to this problem, it’s a lame workaround at best. There are plenty of reasons why people would use the backing field in their code instead of the property and if they run into this problem, they definitely will blame the ORM. And rightfully so, i might add.

Posted in NHibernate | 12 Comments »

Must Everything Be Virtual With NHibernate, Part II

Posted by Davy Brion on 23rd September 2009

I already tried to explain this before, but here’s a simple example from a presentation i recently did on NHibernate:

transitive_persistence4

As you can see, only the properties of associations that are eligible for lazy-loading are virtual in this piece of code, because that is what many people seem to want. There are actually 2 different ways in which this can cause problems… can you spot both problems?

Posted in NHibernate | 10 Comments »

Slides Of My NHibernate Talk

Posted by Davy Brion on 10th September 2009

I’m giving a talk on NHibernate for the Belgian Visual Studio User Group right now (gotta love scheduled posts!). You can download the slides of the presentation here. I don’t like most typical technical presentations, so i wanted a slightly different approach. So this presentation probably isn’t like most presentations that you may be used to. This is also the first time i’m giving a ‘big’ talk for a group of people that i don’t know personally, so hopefully, it’ll be alright and i won’t screw up ;) .

If i did screw up: sorry, but at least it was free :p

Posted in NHibernate | 15 Comments »

Of Course NHibernate Is Slow When You Use It Incorrectly

Posted by Davy Brion on 19th August 2009

Just saw the following post where the performance of NHibernate and Entity Framework is compared for a couple of different operations. Spoiler alert: NHibernate loses. As it typically does in these kinds of ‘benchmarks’ or ‘comparisons’ that seem to pop up frequently lately.

For some reason, a lot of people seem to think that opening an NHibernate session and performing thousands of operations is a valid use case. It’s not. Far from it actually. And with all of the features that NHibernate offers, it can’t possibly perform well in such a scenario. See, an NHibernate session is a unit of work. A unit of work is a business transaction which is typically short and small, but it should never be something huge. Your DBA probably won’t appreciate huge database transactions on the database either.

Whenever you load an object through NHibernate, it will be tracked by the session that loaded it. That means that the NHibernate session keeps a reference to it, and performs a series of checks on it periodically, depending on what you’re doing and some configuration settings such as the FlushMode. For instance, suppose you’ve loaded a hundred different entities in one session. If the FlushMode is set to automatic, it means that NHibernate will perform a dirty check for each entity associated with the session before each query is executed. The more entity instances you’ve loaded, the longer this takes (obviously). If you take this to an extreme level, like loading thousands of entities like most of these ‘benchmarks’ do, performance will naturally be horrible.

Each entity instance is also stored in the first level (or session level) cache. That means that whenever you retrieve a row from the database, NHibernate will check if an instance of that row already exists in the first level cache. Again, the more instances you’ve loaded, the larger the overhead of this will be. There are also a lot of possible extension points where you can plug in custom logic. Again, there is a very minor cost that comes with this extensibility and as you can expect, that minor cost can add up to something much more noticable once you start dealing with an unreasonably large number of instances in your session.

Always keep in mind that an ORM (and this goes for every ORM) is most suitable for OLTP. Using an ORM for batch processing jobs or large data processing operations in general is simply put a bad idea. And they will never perform as well as other solutions in these scenarios. So please don’t bother even benchmarking ORM performance in non OLTP usage because it quite simply doesn’t make sense to do so, and the results will be completely untrustworthy anyway.

An ORM can offer you nice performance gains in OLTP scenarios simply by trying to minimize database connectivity, minimizing the number of database operations, and relatively sane caching usage. Unfortunately, these are aspects that are never tested in these ‘benchmarks’ or ‘comparisons’.

Posted in NHibernate, Performance | 15 Comments »