Monthly Archives: January 2011

Take the Time to Go Fast

This week, I have been working my tail off and making what feels like slow progress, but I have been keeping in mind what Uncle Bob calls The Primal Conundrum.

Programmers face a conundrum of basic values. All developers with more than a few years experience know that previous messes slow them down. And yet all developers feel the pressure to make messes in order to meet deadlines. In short, they don’t take the time to go fast!

True professionals know that the second part of the conundrum is wrong. You will not make the deadline by making the mess. Indeed, the mess will slow you down instantly, and will force you to miss the deadline. The only way to make the deadline—the only way to go fast—is to keep the code as clean as possible at all times.

What I have been working on is relatively complex. It is taking way more time than I estimated (I’m horrible at estimating), yet I’m still taking the time to write my tests (and keep the old tests passing). But are my tests slowing me down?

The answer is not always no, but in this case, I would say it is an emphatic no! As I said, I am writing some relatively complex stuff – security related stuff. I would I want to write it and just run a couple of manual functional tests and assume I have it covered? That sounds like a bad idea. What if I ran a bunch of manual functional tests, not just a few? That might be sufficient, but now we are not saving any time over the automated unit tests and I don’t get to save the tests for all the ways the code will develop in the future. Speaking of which, all of those tests I’ve already written are really saving me a bunch of time. All of those tests that stop passing when I add security means that I have to do something. Those tests aren’t getting in my way. They are reminding me, “Don’t forget to take me into account, too!”

Furthermore, Mr. Martin is not really talking about tests per se, but clean code. If you’re writing something complex, what better way to force yourself to break it into smaller, less complex chunks than by writing the tests first?

Anyway, just wanted to dash this off before I get back to the salt mine. I’m still under pressure and I have more tests to write.

CONCAT Gotcha between MySQL and HSQLDB

Hibernate abstracts most of the data access layer so you can switch out database platforms without changing any code (unless you count configuration as code). This allows me to use HSQLDB for my tests and MySQL for production. I love HSQLDB for integration tests. Running embedded in memory it’s super fast and you don’t have to configure a server or worry about the existing state of the database when you start your test suite (it’s empty!).

There are, of course, perils to testing with it when your production database is something else (and it almost certainly is). I have a Person class with a formula name field:

@Entity
public class Person extends Party {
  private String lastName = "";
  private String firstName = "";
  @Formula("ltrim(concat(concat(first_name, ' '), last_name))")
  private String name;

  @Override
  public String getName() {
    this.name = (firstName + ' ' + lastName).trim();
    return name;
  }
...
}

It took me a while to arrive at that formula, though.  The first one I tried was concat(first_name, ' ', last_name) but HSQLDB complained that it didn’t know the concat formula.  I knew it did, so I found that strange, but tried hunting around for alternatives.  I then tried first_name || ' ' || last_name.  That worked and all of my integration tests were passing so I thought everything was great.  I deployed to MySQL and didn’t get any errors, so everything’s working like a charm, right?

Nope.  But you knew that – why would I bother to write about that? Anyway, MySQL doesn’t complain about syntax because it is treating the || as a logical ‘OR’ and is somehow able to come up with 'Jason' OR ' ' OR 'Erickson' = 0.  Why 0? Well, if you have a string where MySQL expects a number, it will try to convert the string to a number.  A string that cannot be parsed to a number is not an error.  It’s 0.  So 0 || 0 || 0 = 0.

Anyway, now I don’t have any errors, but everybody’s name now evaluates to 0.  Except that it doesn’t.  See, that getter for name? That was there because I wanted it to work whether the Person had already been persisted or not.  That means that it looked like it was working in all of the code that accessed the bean except… find by name.  The query,  “FROM Party WHERE name = ?” was never finding my people by name.  This was quite a puzzle for me.

Well, anyway, I finally figured out what the problem was, and a little “aha” flash told me that the HSQLDB version of concat did not support an arbitrary number of parameters, so concat(first_name, ' ', last_name) wouldn’t work, but concat(concat(first_name, ' '), last_name) would.  Then I added an ltrim to take care of the case with no first name and I was set.

I’m Posting Every Week in 2011

I’ve decided I want to blog more. Looking at my site’s stats, they are quite modest, but I had assumed when I started writing this thing that I would have close to zero hits per day. But it looks like it’s much more than zero (which isn’t saying much, but still… it’s all about expectations, right?). With that in mind, I think this blog needs a little more attention so there’s something for people to read besides that I thought that Spring Roo Sucks (which is too harsh). Therefore, my goal is to have a new post on this blog at least once per week for all of 2011.

I know it won’t be easy, but it might be fun, inspiring, awesome and wonderful. Therefore I’m promising to make use of The DailyPost, and the community of other bloggers with similiar goals, to help me along the way, including asking for help when I need it and encouraging others when I can.

If you already read my blog, I hope you’ll encourage me with comments and likes, and good will along the way.