CodeBetter.Com
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @CodeBetter

Jeffrey Palermo (.com)

Blog moved to www.jeffreypalermo.com

NHibernate 1.2 released! upgrade experience report - level 300

First, kudos to the NHibernate team for getting the 1.2 release finalized.  Get it here.

The first thing you'll notice when upgrading from 1.0.3 is that class mappings are now lazy by default.  If you want to just upgrade your app, you'll need to go through  your mappings and mark each class mapping as lazy="false".  Then, everything should work. 

Another semantic change that I noticed in my codebase is that before a new NHibernate ISession is used, the Transaction property was null in v1.0.3.  With v1.2, this object is not null (but isn't active, either).  I found this because I had a check for null in my NHibernate management code.  No biggie, but something I noticed.

v1.2 brings a Dialect for SQL 2005, so that's cool.  I had been using the SQL 2000 Dialect for 2005, and it worked just fine because SQL 2005 is pretty much backward compatible.

Another biggie is the addition of some ICriterion implementations for subqueries.  We're all used to using Expression.Eq() for forming the WHERE clause, but now we also have Subqueries.* for creating a WHERE clause with a subquery.  This is useful for checking to make sure a bag or list has at least one object while using an instance of ICriteria.

The upgrade was pretty painless, and I love it.



Comments

Ayende Rahien said:

You can also use default-lazy="false" in the <hibernate-mapping element.

In general, I would suggest that everything would be lazy.

About checking for emptiness, there is the new:

Expression.IsEmpty()

Expression.IsNotEmpty()

That are easier than subqueries for the scenarios that you describe.

# May 11, 2007 5:12 PM

Jeffrey Palermo said:

@Ayende,

What is the reasoning behind the recommendation that all classes be marked as lazy?

Usually, when I query for the aggregate in my domain model (say Order), I want the actual Order and all LineItems in my "set".  I don't want another query the first time I call a property on the Order.  I would think I want Order not to be lazy.

Note that I'm calling session.Load(orderId).

# May 11, 2007 5:25 PM

Ayende Rahien said:

Performance is better this way.

That usually depends on the way you setup associations between the entities. But the classic example is user <-> groups, when you load a user, you may end up loading _all_ the users, and _all_ the groups, if you don't have lazy loading at the right places.

If you aggregate is deep, Order -> Order Lines -> Product, you may want to load just part of that.

Each scenario is unique, of course.

# May 12, 2007 6:02 AM

Cassio said:

As a rule of thumb, I mark my collections as lazy (select) and simple many-to-one associations as eager (join).

But, of course, it depends on the scenario.

# October 10, 2007 3:38 PM

About Jeffrey Palermo

Jeffrey Palermo is a software management consultant and the CTO of Headspring Systems in Austin, TX. Jeffrey specializes in Agile coaching and helps companies double the productivity of software teams. Jeffrey is an MCSD.Net , Microsoft MVP, Certified Scrummaster, Austin .Net User Group leader, AgileAustin board member, INETA speaker, INETA Membership Mentor, Christian, husband, father, motorcyclist, Eagle Scout, U.S. Army Veteran, and Texas A&M University graduate. Check out Devlicio.us!

This Blog

Syndication

News

Headspring Systems

View Jeffrey Palermo's profile on LinkedIn

See my new blog at .jeffreypalermo.com