Monday 22 June 2009

Microsoft's Web Standards

Just a little light humour from the microsoft website...





Oops!

NHibernate Parameter Error

We were getting an IndexOutOfRange Exception when trying to save a Period object in our application. Invalid Index 17 for this SqlParameterCollection with Count=17

It was a little confusing as we'd not seen any error like this before:




After a bit of head scratching, we interrogated the mapping file, see if you can spot the error:



Did you spot it? Well, there are two columns called "MORId", one in the main class, and one in the component AgreedWorkLevel. The important thing to remember is that components are stored in the same table and although they are in different classes, they need to be uniquely named.

I would imagine if you wanted the component property to be the same as the class' property, you could link this in code and leave NHibernate pointing to the single reference point.

NHibernate Querying - Getting list of null objects

This weekend we had a very bizzare error on NHibernate. We did a query, nothing clever in it, but we got a list of null's back. The length of the list was the expected value but each item was null.

IList result = PeriodFactory.GetAllPeriods(person);
if (result[0] == null)
Throw New Exception("Item Was Null!");

It was throwing the null exception. So what was NHibernate doing?

Well, let's look at the mapping file:

It all looks OK. It certainly compiled and ran OK. So maybe it was something to do with the code querying the Periods:




p>Well, doesn't seem to be anything wrong here. Maybe NHibernate is not generating the SQL correctly. So using the NHibernate Profiler I checked out the SQL being generated:



Well, even this looks fine. Things are getting very strange! What could be going wrong. NHibernate has worked fine for the last 30 odd classes we'd persisted. What was so strange now? Well, another feature of the NHProfiler is to view the results that are returned. So that was the next stage:


This was the first clue we had. Notice the first column, it is blank, yet it is suppose to be the primary key. So what happens if we try loading a record based on the primary key. This is the most basic of operation, therefore surely this will work. A little hacking of the code for testing:


Three guesses for what result was? you guessed it, sweet Nothing, value 3 did exist in the database, so this should have worked. NHibernate was clearly not being able to create the object. So the query brought back the right number of results. The Get did not. Let's take a closer look at the table structure and compare the primary keys:





Wait! what is this? we have a column called PeriodId (highlighted) that is not the primary key. What is going on here, where did that column come from?


I rechecked the mapping file to located any stray PeriodId's but the only ones were the Foreign Key values which correctly are in the Referenced Table. Then I remembered SchemaUpdate. It was updating the table based on the schema's. My naming convention was class has PK of "Id" and the database was "{tablename}Id" I'd added the column attribute at a later stage and the Update had obviously updated the table to include the new column.


This must be considered a bug in the schema update as it should have updated the primary key and not created a random new column.


With thanks to my trusted memory (eventually) and the great NHProfiler we've managed to get to the bottom of this frustrating issue. Moral of the story, be careful with what the schema update is actually doing...

Friday 19 June 2009

Virtual PC Installation woes

Virtualisation is a great technology. Not only can we test installs of applications against pretty much any operating system, we can also test websites against different browsers (such as IE 6, 7, 8) which do not normally run side by side.

However, I came across a rather annoying, undocumented feature of Microsoft Virtual PC 2007 this week. Having created a VM on my laptop, I wanted to move it to my main PC where it's final home will be. I am running Vista Business (no comments pls) and when I tried to install it I received an error product.cab is corrupt. I first thought this was a bad download, so I redownloaded it - same result.

Bizzare. I then tried the Service pack 1 version, after all this should fix lots of issues, and maybe this would be one of them. Sadly, no. I got the same error.

I then tried to download the version via my MSDN subscription, rather than the public download. Sadly, same result.

I then decided, I would just install VMWare's player and convert my MS VPC to a VMWare version. Sadly, I had a similar error when trying to install VMWare Player.

I'd not had this issue before, so was now quite stumped. I had been trying to install this over a remote deskop connection, so when I returned home, I tried installing it locally. I got the same issue.

Just before giving up, I remembered that old, rarely known trick... I restarted the computer. Low and behold, the next time I tried to install it, everything was fine!

So if you are getting this error, don't be afraid to try the good old restart!

Monday 1 June 2009

Code Monkey on Speed

Recently, I was on an NHibernate course, with Ayende Rahien, a prominent figure in the NHibernate world. He demonstrated all the various mappings and code needed to use NHibernate. I was seriously impressed with is ability to write code and more importantly, the speed at which he did.

Usually, I am very good at following what people are doing and learning that way. Ayende raised the bar a level with his speed of typing and of code refactoring. Super human powers to refactor code, way beyond your rename and copy/paste tools available. Then I remembered the good old C Resharper addon that you can get from http://www.jetbrains.com/resharper/index.html

I have been using it this past week (you may have noticed the slight lack of posting! I've been busy playing!) and am fully amazed with the flexibility and speed increase in development I have seen.

From my previous post about Oracle and Specifications, this week has been very much about creating a whole new business layer for our application, on that will use NHibernate to connect to both SQL server and Oracle. All my business objects will implement and interface (as all good business layers should!) and Resharper has allowed me, with a few key strokes to:

  • Create the concrete class
  • Make it public
  • Implement the interface (with public virtual auto properties) - NHibernate requires virtual properties
  • Move the concrete class to a file of it's own name
  • Manually dragging the class into it's own folder structure
  • Resharper then offers to update the namespace to match folder structure and adds an using statement where needed to refer to the old namespace

With the addition of automated code snippets (i made an interface property snippet to save even more time) I have created half the application in 3 days!

If I didn't have to buy a license for Resharper, I'd definitely buy those guys a pint! Maybe they deserve the pint anyways, it certainly has saved *lots* of time. Try it out and see what you think.