After spending a few nights trying to test NHibernate eager loading with Spring.NET framework’s AbstractTransactionalDbProviderSpringContextTests, I finally found the trick.
First, clear the session (cache). Second, reload the object. Third, close the session. Finally, verify that the dependent object was loaded correctly and not proxied.
The code below shows a test to check that the product type is loaded with a product.
[Test]
public void GetProductShouldAlsoLoadProductType()
{
var productType = productTypeRepository.Get(0);
Product obj = new Product("A product", productType);
productRepository.Store(obj);
Flush();
// Empty session cache. Clear all loaded objects.
SessionFactory.GetCurrentSession().Clear(); // (1)
var loaded = productRepository.Get(obj.Id); // (2)
Assert.That(loaded, Is.Not.Null);
// Close current session to make sure relevant objects are not proxied.
EndTransaction(); // (3)
Assert.That(NHibernateUtil.IsInitialized(loaded.ProductType), Is.True);
Assert.That(loaded.ProductType.Name, Is.Not.Null.Or.Empty);
}
Note that the order of execution is important. You must clear the cache (1) before reloading the object (2) before closing the session (3) before testing your assertions.
If we do not clear the session cache in step (1), reloading the object (2) then closing the session (3) will still make the test pass. The reason is that even though the session is closed, the proxied object is there in the cache, literally meaning it has been loaded (and initialized). You can access the product type’s properties without any errors.
On the other hand, if you clear the session cache in step (1), loading the object in step (2) will create a proxy to ProductType class instead of a fully initialized object. When you close the session (3), the assertions will fail, and if you access any property of product type (besides its ID), you’ll get an exception saying the session has been closed.
ป้ายกำกับ:nhibernate