Archive for March, 2009

New Poll: What’s The Worst Part About Software Development As A Career?

14 commentsWritten on March 31st, 2009 by
Categories: About The Blog

Alright, time for a new poll. Being a software developer is a pretty nice job, but it definitely has some downsides to it. Which parts do you dislike the most about this job?

  • Too many incompetent managers
  • Buzzwords
  • Dealing with incompetent devs or devs that just don't care
  • Dealing with customers who change their mind all the time
  • Tool vendors that don't focus on proper software development practices
  • Too much overtime
  • Corporate politics

You can select as many options as you want. Again, for the people who only reed this through their RSS reader, you can vote on my site at the top right corner. I'm not going to add more options to the poll, but feel free to mention other downsides to this career in the comments :)

Must Everything Be Virtual With NHibernate?

52 commentsWritten on March 30th, 2009 by
Categories: NHibernate

If you've ever used NHibernate 2.0 or later, you will have undoubtedly run into the following runtime exception a couple of times:

NHibernate.InvalidProxyTypeException: The following types may not be used as proxies: NHibernateExamples.Entities.OrderLine: method get_UnitPrice should be 'public/protected virtual' or 'protected internal virtual' NHibernateExamples.Entities.OrderLine: method set_UnitPrice should be 'public/protected virtual' or 'protected internal virtual'

Oops... we forgot to make the UnitPrice property on the OrderLine entity virtual. But why does it need to be virtual in the first place? That's a question that many people who are new to NHibernate have.

The quick answer to that question is: because we need members to be virtual in order to do our lazy loading magic/voodoo.

The longer answer is more interesting though. An important feature that any real ORM must have is transparent Lazy Loading. If you retrieve an object through an ORM, you don't want it to automatically pull in an entire object graph (not by default anyway), yet you don't want to litter your code with checks to see if certain associations have been loaded yet, and then loading them if necessary. This is the ORM's responsibility. Ideally, you want to be able to access properties and have the ORM load the necessary data upon first access of those properties if the data hasn't been retrieved yet.

NHibernate has this ability, yet it doesn't require you to inherit from some kind of NHibernate base class or implement any interfaces or anything like that. So how does it work? Well, NHibernate uses proxies of your classes at runtime whenever lazy loading is required. Ok, so what exactly is a proxy? In this case, an NHibernate proxy is a type which is generated dynamically when NHibernate is initialized for your application (this only happens once upon application startup). A proxy type will be generated for each of your entities that hasn't explicitly been mapped to avoid lazy loading (more on this later). A proxy type for one of your entities will actually inherit from your entity, and will then intercept each possible call you can perform on that type.

Let's discuss a small example that might make things clearer. Suppose you have an Order class. The Order class has properties such as Employee and Customer, among others. But when you load Order instances, you might not always want the Employee property to already contain the real Employee entity instance. Same thing goes for the Customer property. By default, NHibernate considers each entity type as eligible for lazy loading unless it's been explicitly configured not to (again, more on this later). So when NHibernate is initialized, it will know that it needs to dynamically generate proxy types for Customer and Employee. Let's just assume these types will be named CustomerProxyType and EmployeeProxyType (they wouldn't be called like that btw, but it doesn't matter). Now suppose that you are retrieving an Order instance (or a bunch of them, doesn't really matter) and you don't instruct NHibernate to already fetch the Customer or Employee data. You haven't requested the Customer or Employee data, so it shouldn't be there, right? But it shouldn't be null either, right? So NHibernate assigns an instance of the CustomerProxyType class to the Customer property, and an instance of EmployeeProxyType and initializes both proxies so that they contain their identifier value, which you already have in memory anyway after selecting the order record.

You can safely use the Order instance(s) and you can even access the Employee and Customer instances and nothing will happen. But, whenever you access any of the non-identifier members (that means properties and methods) of a proxy instance, NHibernate needs to make sure that the data of either the Customer or the Employee (depending on which one you're using) needs to be fetched from the database. So how does NHibernate do that? The proxies will override all of your properties and methods and when one of them is accessed, NHibernate will either fetch the data of the entity if it's not present yet and then proceed with the original implementation of the property or the method, or it will immediately call the original implementation if the data was already present.

This is basic OO... your entities are base classes to NHibernate's proxies, and those proxies need to add a little bit of behavior to your entities' behavior. In order to do that, NHibernate needs to override every public member to make sure that this extra behavior is triggered at the appropriate time. Now, there are quite a few people who dislike this requirement. First of all, there is a minor performance cost to calling virtual members as opposed to calling non virtual members. However, this performance cost is really extremely small and in practically every situation it's completely negligible. This extra cost certainly doesn't even compare to some real world performance costs, like hitting the database more often than you should or retrieving more data than you really need. Another reason why some people don't like this is because they don't like to enable derived classes to override whatever member they want to. In some cases, this is a valid objection. In most cases however, it's pure Intellectual Masturbation which offers no real value at all. There are other ORM's that don't require you to make your members virtual and they are still able to offer lazy loading features. But those ORM's usually require you to either inherit from a specified base class, or to implement one or more interfaces that the ORM will use. In both cases, i'd argue that this pollutes your entities far more than virtual members do, but that's just my opinion.

But for those cases where you really do not want to make members virtual, and don't mind forgoing on the lazy-loading features of NHibernate, you can simply map those entities to not enable lazy loading at all. You could just map an entity like this:

  <class name="OrderLine" table="OrderLine" lazy="false" >

Setting the lazy attribute to false will ensure that NHibernate will not create a proxy type of your entity type, and that you will always be dealing with instances of the actual type of your entity instead of a possible proxy type. It also means that you will never be able to use any kind of lazy loading when it comes to retrieving instances of these entity types.

Avoiding MySQL’s MAX_JOIN_SIZE Limit With NHibernate

2 commentsWritten on March 30th, 2009 by
Categories: NHibernate

We're working on an application which has to use a legacy MySQL database. So far, we haven't really had any problems with MySQL (apart from the dreadful legacy schema but that's another issue) but today, i started getting an exception with the following message:

The SELECT would examine more than MAX_JOIN_SIZE rows; check your WHERE and use SET SQL_BIG_SELECTS=1 or SET SQL_MAX_JOIN_SIZE=# if the SELECT is okay

There is a certain complex view in our application which apparently hits this default limit set by MySQL once there is a certain amount of data present. The view itself is a costly one... it really does need to do a whole lot of joins and rewriting it to use less joins would probably take a long time.

So i figured the better option in this case would be to set the SQL_BIG_SELECTS option to 1. The only problem was: how? It's not a setting that you can pass through the connection string (or at least, i did not find a way to do so) and NHibernate is taking care of all of the database communication.

I remembered a trick i had used earlier, which is to extend NHibernate's DriverConnectionProvider. It could then set the setting with the appropriate value whenever the connection is opened, like this:

    public class CustomConnectionProvider : NHibernate.Connection.DriverConnectionProvider

    {

        public override IDbConnection GetConnection()

        {

            IDbConnection connection = base.GetConnection();

            EnableBigSelects(connection);

            return connection;

        }

 

        private void EnableBigSelects(IDbConnection connection)

        {

            using (var command = connection.CreateCommand())

            {

                command.CommandText = "SET SQL_BIG_SELECTS=1";

                command.ExecuteNonQuery();

            }

        }

    }

After that, you just set the DriverConnectionProvider to use in your hibernate.cfg.xml file like this:

    <property name="connection.provider">MyProject.Infrastructure.NHibernate.CustomConnectionProvider, MyProject</property>

And all is well.

Support Of Commercial Software vs Open Source Software

7 commentsWritten on March 29th, 2009 by
Categories: Opinions

I just read a post by Bobby Johnson titled: Requesting Contracted .NET OSS Bug Fixes from the Community. Bobby works for a company where he can't easily sell the idea of using Open Source Software (OSS) in his projects to management, mainly due to the support issue. A lot of managers have this misconception that because a piece of software comes from a commercial vendor, they will receive proper support from this commercial vendor. With OSS, there usually isn't any kind of guaranteed support. Let's take a closer look into the commercial vs OSS support stories, shall we?

Let's discuss support for OSS first. In the OSS world, there are no guarantees. If it works for you, great. If it doesn't... well, this is where the problems begin. Generally, you contact the developers either through their mailinglist or their issue tracker. If you're out of luck, you get no response. If you're using an actively maintained OSS library (and you shouldn't use inactive OSS projects unless you are willing to maintain it yourself in case of problems), then you will most likely receive at least some kind of response. The issue or bug might be acknowledged, or it might be dismissed.

Let's consider the worst case scenario first. The bug or issue you reported has been dismissed. When you're dealing with healthy OSS projects, your bug or issue will almost never be dismissed without a justified reason. If they do dismiss it, make sure you actually understand why. Usually, it's because you're using it wrong in some way. And yes, it actually is very possible that you are using something created by others in an manner which is incorrect. Your mistakes will either be pointed out to you, or you will find people (on the mailinglists or on people's blogs) who have run into the same 'issue' and have already found a workaround.

If your bug or issue is acknowledged it usually gets fixed pretty quickly. Now, in some cases, real bugs/issues don't get fixed immediately, usually because no good solution which won't introduce other problems has been found yet. In this case, you're pretty much out of luck unless someone has found a workaround. If it does get fixed, the project might release a bugfix release (not all projects do), or they will tell you that the issue has been taken care of in the trunk and that you can either use that, or wait for the next major release. If you can't wait, you can usually still backport the fix from the trunk to the latest release.

As you can see, there are quite a few options in the OSS model. A lot of it depends on the healthiness of the piece of OSS that you're using. In the absolute worst case scenario, you can still fix it yourself. Will it take you time (and thus, cost you money)? It almost assuredly will. But at least you have the option to fix it yourself, even if it rarely comes to that.

Let's focus on support in the commercial software world now. First of all, i will state that the quality of support from commercial vendors can vary from poor to awesome just as well as it can vary between OSS projects. If you disagree, i would suspect that you (or your employer) either have very deep pockets, haven't really 'been around', or you don't really work in the real world. Let's classify the commercial vendors in 2 possible categories. The first category is for dedicated software vendors. With that, i mean vendors that focus on one or a couple of things and try to do those things really well. Like, JetBrains for instance. The second category is the kind of company that tries to do everything, usually with varying results. Like Microsoft or IBM.

When products from Category 1 vendors become popular and successful over a sustained period of time, they usually have great (or at least good) support. These products usually have a big userbase, so any problems that the software may have (and we all know that every piece of software has problems) are likely to have been discovered by other users already. Often, a workaround will be available already. If not, the vendor is usually pretty quick on the ball with bugfix releases. There are obviously always exceptions to this, but i guess the same rule applies as to when selecting OSS products: consider the healthiness of the project/organization because it truly impacts everything.

And then there are the Category 2 vendors. These are the vendors that are adored by most managers. Nobody gets fired for going with IBM or Microsoft, right? These companies are huge and the odds of them disappearing over the long haul are slim to none. You paid for their products, so they will always support them. Right? I mean, they couldn't possibly get away with shoddy service to their customers in this day and age!

Let's get back into the real world. When you're dealing with Category 2 vendors, the odds of getting high-quality support aren't as high as you'd think they'd be. First of all, these vendors have a huge product portfolio of software that you can use. Some of those products will be great, and some will be horrible. I don't think anyone can honestly state that no Category 2 vendor has ever released a product that wasn't problematic. If you're using one of their high quality products, then you won't likely run into many issues. If you're using one of their slightly less awesome products, you will likely run into issues, sometimes even a boatload of them.

So what do you do? The vendor will have some sort of means for you to communicate about the bugs or issues you have encountered. In most cases, this will be some sort of website. You can register bugs/issues and hopefully, they will be assigned to someone who will look into it. If that happens, you will hopefully get a response which states that it's either a real issue or that the problem is on your end. Notice how this is still very similar to how it goes on the OSS world. If the problem is on your end, you can hopefully find other people who have ran into the same issue and maybe even find a workaround. If not, you are limited to figuring out a workaround for yourself. You don't really have to option to truly fix the problem as you do have with OSS (even though that's not always realistic either, but at least there is the possibility).

If the Category 2 vendor actually does recognize the bug/issue, there are a couple of things that can happen. They might give you a bugfix. The bugfix might be issued to you (as their customer) privately which means you're probably paying them a boatload of money in annual license fees and support contracts. Don't count on this kind of treatment unless you work for really big companies and even then, keep in mind that they won't fix every real issue or bug that you might run into. If it's a huge issue, it might be released in the short term publicly. This happens very rarely. If the issue/bug gets fixed but you don't get a short term solution, the vendor will simply tell you "this will be fixed in vNext which will come out in 20{1-or-2-years-from-now}".

Support is always a tricky issue, and there is no valid reason to believe that support of commercial software is inherently better than that of OSS, unless you have deep pockets. Most of us however, don't. This post has been rather long, but it's one of those subjects that easily gets me aggravated because i've suffered from crappy support from commercial vendors (particularly Category 2 vendors) just a few times too many. I've also had to deal with managers who's blind faith in commercial vendors was truly astonishing a couple of times too many. Have i been burned by OSS support before? Definitely, but at least those people don't make false promises and you do always have the option of fixing something yourself, no matter how complicated it might be.

Choosing which pieces of software to use should IMO be based on their intrinsic value, not on the company or organization that is behind it. If you can afford premium support, then great, go for it if you want. If you can't, don't assume that the typically provided support will be better than that of OSS projects. And no matter how great the support may be, you're often better off choosing reliable pieces of software where you are less likely to encounter the need to seek support in the first place. If the software is reliable, then the possible support that you may require is often pretty good as well.

Choosing a piece of software based purely on the possibility of getting good support is quite simply rather short-sighted. You might just end up with a piece of software that causes you many problems, and the support you had hoped for isn't really giving you all that much extra benefit either. Or you may end up with crappy software with great support, but wouldn't it have been better if you could've avoided the crappy software in the first place? Just pick the right tool for the right job.

Silverlight Localization Gotcha

2 commentsWritten on March 27th, 2009 by
Categories: Silverlight

Wasted a bit of time figuring this out, so i'm posting it here for future reference. We have this multi-language silverlight app where the UI needs to be shown in either English or Dutch. So you know, i copied my TextResources.resx file (which contains the translated strings in English) and created a TextResources.nl.resx file where i replaced the English strings with the Dutch strings.

In the output folder of the Silverlight project, you can clearly see that the Our.KickAss.Silverlight.Project.resources.dll file is located in the 'nl' folder. The XAP file that is being copied to the actual web project however, doesn't contain the dutch resources.

Apparantly, the key to 'fixing' this is opening the .csproj file of your Silverlight project, and then you need to modify the SupportedCultures element so it contains the cultures you're supporting:

<SupportedCultures>en;nl</SupportedCultures>

There might be a way to do this from the UI within Visual Studio, but i sure didn't find it anywhere.

And now you can simply switch between the translations setting the generated resource class's static Culture property to the culture you want, for instance:

            TextResources.Culture = new CultureInfo("nl-BE");