Getting rid of the nulls in your life

There's nothing so annoying as having written some pretty cool code, but then somewhere in the surrounding code suddenly a nullpointer exception appears.

Nullpointers are evil, I think that's pretty clear, but you as a developer can actually reduce the amount of possible nullpointers!

From the experience in projects I've worked on, it helps to:

 

1. Use final (immutable) fields on your class where possible. For hibernate entities this is often not possible or very inconvenient, but in other classes this prevents accidentally setting the field to null.

 

2. Apply the 'fail early'  principle. Don't let the troubles of inner components affect the outer ones. If bad things happen that cannot be resolved, such as invalid input on one of the public methods at the component, it usually means throwing a runtime exception. Don't just return null and make others do the dirty work.

 

3. Always describe the null case for non primitive return types on methods, in javadoc. If a method needs to return null, it is probably meaningful and worth to explain. If it never does, just say so. Clients of the component can then safely assume that the return value is nullpointer safe.


More reading: 
http://www.javapractices.com/topic/TopicAction.do?Id=134
http://code.google.com/p/guava-libraries/wiki/UsingAndAvoidingNullExplai...

 

0 commentaren

Grails skipping unit tests

Every now and then the Grails (2) framework surprises me. Sometimes in a good way, and sometimes in the worst possible way.

It turns out that when the path your Grails project is in contains a percentage sign, the build does not work correctly. I've seen two effects (depending on various settings):

  1. Grails starts, but the compilation of plugin classes fails (classes not found)
  2. Grails starts, compiles, starts testing, but then does not actually run any tests.

The really annoying part in this is that there is no error message, no build failure, no warnings. Just silence, and unit tests are not being run. Sigh.

The Grails build system (not Gradle) does not handle paths very well. Always make sure that the path to your project is 'simple'. This means no funny characters and staying clear of common grails artifact names (and possibly even 'conceptual' names).

 

0 commentaren

Outer joins and domain classes

When working with GORM domain classes and using DetachedCriteria (for example the 'where' method on domain classes), you will notice at some point that all joins will be inner joins!

 

If the database setup requires an outer (left) join, then the default ,GORM api has no way to specify this, so you will need a workaround.

 

This workaround works by looking into the GORM system at the moment just before the detached criteria become actual hibernate criteria. At that moment it is possible to use the Hibernate api itself that does allow specifying the relation join type.

 

The reason of the lack of support for outer joins seems to be that the detached criteria system is an abstraction not only over hibernate, but also over other NoSQL solutions that do not support this at all.

Here's the actual workaround (groovy code obviously):


List<?> listWithOuterJoin(DetachedCriteria criteriaBuilder,
    Map resultParameters, Map<String,String> outerJoinAssociations) {
       return criteriaBuilder.withPopulatedQuery(resultParameters, null) { Query query ->
           Criteria criteria = query.@criteria
           outerJoinAssociations.each { key, value ->
               criteria.createAlias(key, value, org.hibernate.sql.JoinType.LEFT_OUTER_JOIN)
           }
           query.list()          
    }
}

Usage:

  1. Create a detached criteria instance using any of the GORM api methods
  2. Use aliasses for the relations that you need an outer join for (example: for Person.children, their name can be referred to with 'c' as an alias meaning a reference would become c.name in your criteria query)
  3. Feed the detached criteria to the helper method below together with a map of outer join aliasses in the form of ["children":"c"].
  4. The result (in this setup) is a list of results from the criteria

More info on detached criteria here.


0 commentaren