views:

47

answers:

1

I found what I thought was a great article by Ayende on creating a simple base test fixture for NHib unit testing with SQLite.

My question here is the code for a test case in concrete test fixture. In EX_1 below, Ayende wraps both the save a fetch in a transaction which he commits, and has a Session.Clear in between. This works, or course, but so does EX_2.

All things equal I'd prefer the more compact, readable EX_2. Any thoughts on why the additional code in EX_1 is worth a bit of clutter?

Cheers,
Berryl

==== EX_1 =====

[Fact]
public void CanSaveAndLoadBlog_EX_1()
{
    object id;

    using (var tx = session.BeginTransaction())
    {
        id = session.Save(new Blog
        {
            AllowsComments = true,
            CreatedAt = new DateTime(2000,1,1),
            Subtitle = "Hello",
            Title = "World",
        });

        tx.Commit();
    }

    session.Clear();


    using (var tx = session.BeginTransaction())
    {
        var blog = session.Get<Blog>(id);

        Assert.Equal(new DateTime(2000, 1, 1), blog.CreatedAt);
        Assert.Equal("Hello", blog.Subtitle);
        Assert.Equal("World", blog.Title);
        Assert.True(blog.AllowsComments);

        tx.Commit();
    }
}

==== EX_2 =====

[Fact]
    public void CanSaveAndLoadBlog_EX_2()
    {
        var id = session.Save(new Blog
                                 {
                                     AllowsComments = true,
                                     CreatedAt = new DateTime(2000, 1, 1),
                                     Subtitle = "Hello",
                                     Title = "World",
                                 });

        var fromDb = session.Get<Blog>(id);

        Assert.Equal(new DateTime(2000, 1, 1), fromDb.CreatedAt);
        Assert.Equal("Hello", fromDb.Subtitle);
        Assert.Equal("World", fromDb.Title);
        Assert.True(fromDb.AllowsComments);

    }
+1  A: 

I believe with NHibernate it is encouraged to use transactions even when you you're only querying. Check this article http://nhprof.com/Learn/Alerts/DoNotUseImplicitTransactions.

Also your EX_2 code might not hit the database depending on what type of primary key you're using. If you're using Identity key that autoincrement, NHibernate will hit the database and get a primary key, but if you using guid, guid.comb, or hilo, you won't hit the database at all. So your Get would be grabbing what NHibernate has cached in memory unless you do a commit changes and then clear the session so you know you got nothing in memory.

Emmanuel
@Emmanuel - I didn't know that about always using transactions for read operations with Hibernate. Thanks for pointing it out. Chapter 11.2 of the docs seem to confirm this as well (http://docs.jboss.org/hibernate/core/3.3/reference/en/html/transactions.html) "Always use clear transaction boundaries, even for read-only operations."
dcp