views:

36

answers:

1

I'm loading an instance twice from the same session, but nhibernate returns two instances which I am assuming means that the entity is not in the first level cache. What can cause this sort of behaviour?

Test:

        using (new TransactionScope())
        {
            // arrange
            NewSessionUnitOfWorkFactory factory = CreateUnitOfWorkFactory();
            const int WorkItemId = 1;
            const string OriginalDescription = "A";

            WorkItemRepository repository = new WorkItemRepository(factory);
            WorkItem workItem = WorkItem.Create(WorkItemId, OriginalDescription);
            repository.Commit(workItem);

            // act

            using (IUnitOfWork uow = factory.Create())
            {
                workItem = repository.Get(WorkItemId);
                WorkItem secondInstance = repository.Get(WorkItemId);

                // assert
                Assert.AreSame(workItem, secondInstance);
            }
        }

Update

The reason for this odd behaviour was this line of code:

            NewSessionUnitOfWorkFactory factory = CreateUnitOfWorkFactory();

When I replaced it with this factory impl:

            ExistingSessionAwareUnitOfWorkFactory factory = new ExistingSessionAwareUnitOfWorkFactory(CreateUnitOfWorkFactory(), new NonTransactionalChildUnitOfWorkFactory());

It works as expected.

+2  A: 

I'm just guessing here, as you did not include the code for your Repository/UnitOfWork implementations. Reading this bit of code though, how does your Repository know which UnitOfWork it should be acting against?

First Level Cache is at the Session level, which I am assuming is held in your IUnitOfWork. The only setting on the Repository is the Factory, so my next assumption is that the code for repository.Get() is instantiating a new Session and loading the object through it. So the next call to Get() will instantiate another new Session and load the object. Two different level 1 caches, two different objects retrieved.

Of course, if your UnitOfWork is actually encapsulating Transaction, and the Factory is encapsulating Session, then this doesn't actually apply :)

Chris Shaffer
Thank you for the quick reply. I can see that I've used the wrong type of factory in my test. I've replaced it with the correct type (which respects if there already exists a session) and it works.
Marius