Archive for January, 2009

My 2 Most Cherished Mistakes

5 commentsWritten on January 29th, 2009 by
Categories: Software Development

Just read an interesting post from Leo Babuata about how important making mistakes can be. I quote:

Yet without mistakes, we could not learn or grow.If you think about it that way, mistakes should be cherished and celebrated for being one of the most amazing things in the world: they make learning possible, they make growth and improvement possible.

I could not agree more. There are two mistakes in particular that have had a huge impact on my career, and that i'm actually very grateful for.

The first was when i once accidentally truncated 4 tables in a production database losing millions of records in the process. I actually learned a few important things from this. Checking your connection string to make sure you're connected to the right database obviously being one of them. Not doing any important work before 8am is another one. The most important thing i learned from this? Being honest about your screw-ups. This happened in an organization where nobody ever makes a mistake (wink wink), yet things go wrong all the time. Whenever someone screwed up, they would call up the people from Operations, blame it on some kind of faulty process or whatever, never taking personal responsibility for it. The result was that the Operations guys made you jump through hoops to get the problem resolved. After my accidental truncation of those production tables, i called the Operations guys who were responsible for our Oracle server, and i said "Umm... i made a stupid mistake, and i accidentally truncated 4 production tables". The silence on the other end of the line was deafening. It was like the guy from Operations was waiting for me to come up with an excuse, so i just asked "how can we get this fixed as soon as possible?". And they just started working on the restoration process (which for some reason takes a couple of hours) immediately, not even requiring me to fill out a support ticket (which meant having to navigate in an application with about 16 tabs, some of them containing between 5 and 10 sub tabs, with each tab having about 20 fields on it).

Lesson learned? If you screw up, be honest about it, don't blame someone else, don't come up with an excuse, just tell them you screwed up. You'd be amazed at how well people react to that, and problems usually get fixed much quicker because of it.

The second huge mistake was about the 4th or 5th project in my career. It was a pretty interesting project, and was a lot of fun to do. It was an application that had to keep a lot of statistics on the usage of an intranet site of a large enterprise. One part of it was a nightly process which would parse the logfiles and store all of the data. The other part was a client tool to consult the data in variety of ways. The first version was great. Performance was pretty good (at first), and the application did what it was supposed to do. The users were happy. I was too.

Then some of the requirements changed. And i changed both tools. Then the requirements changed again, and again, and again. The code was quickly turning into such a nightmare, that i often feared making changes, knowing very well that each change was very likely to introduce new problems. The project turned into a maintenance nightmare (luckily, the only one i ever produced) and after about 2 years i was the biggest proponent of killing it and just buying some tool to do the same thing.

My biggest mistakes in that project were that i hadn't designed my code to enable change in an easy manner, and that i had no tests whatsoever. When i had to make changes, it usually resorted in adding if and/or switch statements here and there, and lots and lots of debugging. I just didn't know any better at the time. It actually took me a few more years before i actually started writing tests, but it did have an immediate impact into how i started designing and writing code.

Ever since that project, i've been gradually moving towards keeping code loosely coupled and making sure that, when necessary, i could easily change parts of it with confidence, or even replace parts altogether without affecting other parts of code. It took me a while to get there, but these days i'm pretty sure that i can deal with a lot of changes, in pretty much every layer, without causing new problems or decreasing the overall quality of the system. I may have gotten to this point without having first created a maintenance nightmare, but it probably would've taken me a lot longer to realize the benefits to all these hippie patterns and practices that we now subscribe to.

So yeah... learn from your mistakes, and be thankful that you made them.

Introducing the Belgian ALT.NET site

1 Comment »Written on January 28th, 2009 by
Categories: ALT.NET

It took us a while but it's finally here: www.altdotnet.be

We started our local ALT.NET meetings in August, and have been doing them monthly ever since. We usually discuss a certain technical topic (or a few of them), although we sometimes have someone do a presentation as well. Either way, there's a lot of great stuff to learn from these meetings, so if you're a .NET developer who would like to keep improving your skills, be sure to sign up :)

NHibernate and Future Queries, Part 2

1 Comment »Written on January 26th, 2009 by
Categories: NHibernate

In my last post i showed you how we can now use the Future feature in NHibernate. The only downside to the feature is that we only have the Future method in ICriteria, which returns a generic IEnumerable. Which doesn't really lead to nice code when dealing with queries that return a scalar value, or just a single row in general. So i decided to extend the feature a little bit.

I introduced the IFutureValue interface, which only defines a Value property:

    public interface IFutureValue<T>
    {
        T Value { get; }
    }

Then i added the FutureValue method on ICriteria, which returns an IFutureValue instance which behaves exactly like the IEnumerable that is returned by the Future method. If you access the Value property of the IFutureValue instance, it will either execute all of the currently queued Future queries in a single roundtrip, or it will simply return the result if the queries were already executed.

Here's some useless sample code to show off the feature:

            using (ISession session = sessionFactory.OpenSession())
            {
                IFutureValue<int> categoryCount = session.CreateCriteria(typeof(ProductCategory))
                    .SetProjection(Projections.RowCount())
                    .FutureValue<int>();
 
                IFutureValue<Supplier> mySupplier = session.CreateCriteria(typeof(Supplier))
                    .Add(Restrictions.Eq("Id", supplierId))
                    .FutureValue<Supplier>();
 
                IEnumerable<Product> allProducts = session.CreateCriteria(typeof(Product))
                    .Future<Product>();
 
                // the next line causes the 3 queries to be executed
                int count = categoryCount.Value;
                Supplier retrievedSupplier = mySupplier.Value;
 
                foreach (var product in allProducts)
                {
                    // yada yada yada... we're doing something important
                }

This is available starting with revision 4000, or in the official NHibernate 2.1 release.

New Poll: What’s Keeping You From Using NHibernate?

24 commentsWritten on January 25th, 2009 by
Categories: NHibernate

I'm obviously biased, but i think that NHibernate is the best option for data access in the .NET world at the moment. And while we have a lot of users, there's also a lot of people that don't use it. I'm just curious as to why some people aren't using it. So i've set up a new poll with some options you can select if you're not using it. But if you're not using it, do me a favor and leave a comment to explain your selection.

This isn't meant to start a flamewar or anything like that, i'm just genuinely interested in reasons for not using NHibernate.

The options of the poll are:

  • Tried it, just didn't like it
  • Tried it, but had problems that prevented me from using it
  • Can't try it because i have little to no faith in the project
  • Can't try it because i'm not allowed to use it (because of management, technical leads, legal reasons, etc...)
  • Won't try it because i use something else that i'm perfectly happy with
  • Won't try it because i've heard too many stories of projects having problems with it

Also, if there's another reason why you're not using it, please do share :)

NHibernate and Future Queries

9 commentsWritten on January 25th, 2009 by
Categories: NHibernate

As some of you already know, i'm a big fan of avoiding excessive roundtrips by batching queries and/or service calls. For NHibernate, i wrote the QueryBatcher class which makes this pretty easy to do. Ayende recently added a much easier approach for this to NHibernate.

Take a look at the following code:

            using (ISession session = sessionFactory.OpenSession())
            {
                // this executes the first query
                var categories = session.CreateCriteria(typeof(ProductCategory)).List();               
                // this executes the second query
                var suppliers = session.CreateCriteria(typeof(Supplier)).List();
 
                foreach (var category in categories)
                {
                    // do something
                }
 
                foreach (var supplier in suppliers)
                {
                    // do something
                }
            }

This is a really trivial example, but it should be more than sufficient. It simply executes two very simple queries and loops through the results to do something with each returned entity. The problem, obviously, is that this hits the database twice while there really is no good reason for doing so.

With the new Future feature we can rewrite that code like this:

            using (ISession session = sessionFactory.OpenSession())
            {
                // this creates the first query
                var categories = session.CreateCriteria(typeof(ProductCategory)).Future<ProductCategory>();
                // this creates the second query
                var suppliers = session.CreateCriteria(typeof(Supplier)).Future<Supplier>();
 
                // this causes both queries to be sent in ONE roundtrip
                foreach (var category in categories)
                {
                    // do something
                }
 
                // this doesn't do anything because the suppliers have already been loaded
                foreach (var supplier in suppliers)
                {
                    // do something
                }
            }

Apart from the comments, did you spot the difference? Instead of calling ICriteria's List method (which causes the query to be executed immediately), we call ICriteria's Future method. This returns an IEnumerable of the type you provided to the Future method. And this is where it gets interesting. Instead of executing the queries immediately, the queries are added to an instance of NHibernate's already existing MultiCriteria class. Only once you enumerate through one of the retrieved IEnumerables will all the (queued) Future queries be executed, in a single roundtrip. Once they are executed, their result is final (as in: enumerating through the IEnumerable will not cause the query to be executed again).

The example used here is obviously very trivial, but you can use this with any ICriteria so you can very easily start batching your complex queries as well. The kind of query doesn't really matter, as long as it's an ICriteria instance.

This feature will be available in NHibernate 2.1, or if you're using the trunk you can use it starting with revision 3999.