New Windows tablet PC unboxed

I purchased some of the Samsung Series 7 Slate PC’s from the online Microsoft store.  The computer comes with Windows 7, which is touch-enabled, and uses a stylus as well as your finger.  It’s only single touch, though.  We bought them to promptly install the Windows 8 developer preview.  I believe Windows 8 will be a huge catalyst for upgrading inside businesses everyone.  Many business users have looked at their personal iPads hoping for the day where they could carry around a tablet computer and still run all their old software.  With Windows 8, they will be able to.

The mobile space has brought a lot of discussion to our industry for what “normal” is.  The mouse and pointer fundamentally changed the way people used computers.  Now, the pointer is the touch, and you can have many of them (multi-touch).  The fundamentals of computing are changing again.

About 13 years ago, you saw some people carrying around a watch, a cell phone, a PDA, and a heavy laptop computer.  We have seen the watch, cell phone and PDA converge into a single device, the smart phone.  Fewer and fewer people wear wristwatches these days.  13 years ago, people who used heavy laptops also had fully-featured desktop computers.  Now, they have a laptop for all of their computing needs.  The iPad has proven that thin-computing devices can help perform many tasks that we have grown accustomed to using laptops for.  Some people proclaim “thin clients are here to stay”.  I don’t think that’s true.  I think that we are in a temporary transition state where thin tablets are pulling laptops to a smaller form factor.  With Windows 8, the thin tablet can now do just about everything that was possible with the laptop computer.  Gamers and CAD engineers will continue to use specialized computers, but the vast number of business users will find all their needs met with a single tablet computer running Windows 8.  It’s not a far stretch to imagine a laptop dock for the tablet for easy keyboard use in meetings.  Back in the office, a normal dock connects the tablet computer with a full-sized keyboard and mouse for entrenched business applications like SAP or Oracle financials.

Needless to say, we are very excited about the transition to multi-touch computing.  We think many businesses will be upgrading their software to work on Windows 8.

Challenging non-local session scope (session-per-request)

I posted the following on the nhusers mailing list, and Steve Bohlen was nice enough to weigh in.  I was hoping to get broader feedback on this, so I’m posting it here. 

======================================================

I want to challenge a presumed best practice with NHibernate.  I’m challenging it honestly given my experience using it and helping many clients use it as well.

On the official NHibernate community website, nhforge.org, there is an article on session-per-request.  I have used this technique for most of the years I’ve used NHibernate.  I have been able to use it effectively.  But, I couldn’t get over the fact that all of our clients have problems with this and end up in situations where lazy-load queries happen at all layers of the application.

My problem, then, is that this pattern, while technically sound and useful, introduces complexity that requires a deeper understanding of NHibernate to manage.  Because of this, we have begun disposing of the session after each and every transaction.  See here:

public Employee GetByUserName(string userName)
{
    using (ISession session = DataContext.GetSession())
    {
        IQuery query =
            session.CreateQuery(
            "from Employee emp left join fetch emp.Roles where emp.UserName = :username");
        query.SetParameter("username", userName);
        var match = query.UniqueResult<Employee>();
        return match;
    }
}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

Here, I get the employee, dispose of the session, and pass the object back.  For each variation of loading, we have a different method that eager fetches the right level of association or collection.  This way, the application has the data it needs, and there aren’t any lazy-load exceptions.

This approach simplified the code in a few ways:

  • Each query to the database is known, and there is a method for each
  • All queries are executed while the call stack is in the data layer (no UI-level lazy loading)
  • It forces the developer to think about each data scenario

In coaching and training other developers (we actually teach NHibernate in our Agile Boot Camp training class), we have come up with a simple message for how to think about NHibernate and other ORMs.

  1. When moving from stored procedures to an ORM, don’t forget what was good about sprocs (you had a list of every query that would be run against your database)
  2. Use an ORM for just Object to Relational Mapping.  That is the core strength.  The other features, like lazy-loading, can be useful, but they also add complexity
  3. Keep all your relationships and collections mapped as lazy, but don’t allow them to lazily-load
  4. Dispose of a session immediately after using it.
  5. Keep the NHibernate reference out of the your core library and behind data access interfaces.

I’ll pause here because there is nothing wrong with session-per-request technically.  I successfully used it on many projects.  The problem is that it is complicated.  I understand it just fine, but I’m also an NHibernate expert.  Lots of other developers just want to use it and be done with it.  They don’t want surprises.  Elevating the session past local scope up to a global variable brings unintended consequences.  When developing, I might dereference another collection on an object, and NHibernate happily runs another select statement against my database.  As that developer, I don’t have profiler perpetually open to see this happen.  There is absolutely no signal that I just put something undesirable in my application.  Developers need fast feedback on what they are doing.  If there was no session hanging around, the lazy-load invocation would throw and excepting right then.  The developer would then go back and modify the query or decide that we need a new one.  We have used session-per-transaction on two projects now, and it hasn’t led to any other difficulties, so I view it very favorably.

A "best practice" should generally lead a developer to a desirable result.  I think that here, the best practice needs to lead to simplicity, even while the "advanced" practice may still be session-per-request.

I have not drawn a final conclusion, but given the bad effects I’ve seen from this, wouldn’t it be a simpler (better) practice to just dispose of the session immediately and create a few more explicit repository methods for different loading levels? 

I appreciate any discussion that arises from this.  The best place would be on the NHibernate Users mailing list.