19 June 2008

Comparison of "netbook" screen resolutions

I'm thinking about pushing the boat out and getting myself a "netbook" and was wondering whether I'd actually find the relatively low resolutions they offer usable so I knocked up this quick comparison. To make them as usable a possible you'd probably have your browser in full screen mode so that's what I've depicted here.

As you can see both the greater resolutions would be very usable for browsing and the Mini-Note's resolution is brilliant for a 9" screen; being the same as that you usually see on much larger machines.

The 7" EEE PC's 800 x 480 resolution isn't quite enough. You can see in the screen shot the horizontal scroll bar at the bottom and I think that would be a common problem as lots of sites are designed for 1024 pixels as minimum width rather than 800 pixels these days.

To sum up the HP would almost be a viable alternative to a full size laptop if it were more powerful. For now though, it looks like the Acer Aspire One with its good resolution, 1.6GHz Intel Atom processor and excellent price of £199, would be the best one to go for.

02 June 2008

"duplicate association path" bug in NHibernate Criteria API

This problem exists in Hibernate itself as well and, contrary to some comments I've seen in the bug tracker, I believe it is a bug in the Criteria API and not in HQL.

A trivial example

I have a Store type representing a shop which has a collection, Products, containing Product types the shop stocks e.g. "Golf Balls", "Bananas", "Hats" etc. I want to get all the stores who stock both Golf Balls and Hats.

In HQL this would be :

SELECT s 
FROM Store AS s 
INNER JOIN s.Products AS prod1
INNER JOIN s.Products AS prod2
WHERE prod1.Type = 'Golf Balls' 
   AND prod2.Type = 'Hats'

...pretty straight forward and works fine.

In Criteria API this would be:

IList stores = sess.CreateCriteria(typeof(Store))
   .CreateAlias("Products", "prod1")
   .CreateAlias("Products", "prod2")
   .Add( Expression.EqProperty("prod1.Type", "Golf Balls") )
   .Add( Expression.EqProperty("prod2.Type", "Hats") )
   .List();

...again straight forward and seems logical but this produces an error...

NHibernate.QueryException: duplicate association path Products

As I said, it seems like a pretty solid candidate for a bug and it's odd considering surely the meaning of CreateAlias is that I want to use the same association more than once so need to alias it to different labels.

Unfortunately there's no way to get around this issue if you need distinct association joins like the above example and looking at the NHibernate code it doesn't seem like an easy fix. If, however, you can apply your criterion or sorts to the same alias then there is a workaround.

Workaround

NoteThis only applies where you don't require distinct association joins.

If we take a look at this handy NHibernate API reference we see that the two implementing classes for ICriteria are NHibernate.Impl.CriteriaImpl and NHibernate.Impl.CriteriaImpl.Subcriteria.

CriteriaImpl is the root criteria you get calling CreateCriteria on ISession and Subcriteria you get with every call to CreateCrteria or CreateAlias on ICriteria.

First you need to retrieve the root CriteriaImpl for your working ICriteria. Your working ICriteria may be the root but if it isn't you need to recurse up through the Parent property until you reach the CriteriaImpl object.

CriteriaImpl has an IterateSubcriteria method which returns an IList of all its Subcriteria descendants. You can loop through this list checking the Parent and Path properties of each item. The Parent because the value of Path is relative and you're only interested in what will be sibling Subcriteria to the one you're about to add.

If you find a match you can retrieve its alias from the Alias property, otherwise you can add a new alias to your working ICriteria.

Update - Jan 2014

It seems this bug is still not fixed in NHibernate (or Hibernate for that matter) and that it may also affect the LINQ provider. The relevant issues links are:

I'm very tempted to have a go at fixing this myself given there still seem to be a few people struggling with it. Will post another update if I get anywhere.