Null vs. Exception

9th April 2009, 2026

This week a fellow colleague posed the question of whether to return null or throw an exception when looking up an entity from a repository by id. This blog post describes in more detail why I generally prefer to throw an exception.

The Use Case

Most API design decisions really need a context to guide them as the correct decision could be different depending on how the api is going to be used. For my purposes, lets imagine that I am writing functionality into a Spring MVC based web application that would allow a user to change their password.

Working top-down I would have a spring controller along the lines of

public class ChangePasswordController extends SimpleFormController {
  public ModelAndView onSubmit(....) {
    // Get the logged in user id
    // Get the new password
    userManagementService.changeUserPassword(userId, newPassword);
  }
}

As you can see this controller delegates the real work to a UserManagementService which might look something like the following.

public class LocalUserManagementService implements UserManagementService {
  public void changeUserPassword(final Long userId, final String newPassword) {
    final User user = userRepository.get(userId);
    user.changePassword(newPassword);
  }
}

In this code example we see the call to userRepository.get(userId) it is the behaviour of this method that is under discussion, what should happen if no user with the given id is found?

Solutions

Return null

Probably the most common solution to this situation is to just return a null reference from the get() method. With the implementation of the UserManagementService proposed above this would cause a NullPointerException to be thrown when I try to call the changePassword method on the null reference. Therefore I need to write some code to handle this condition.

public class LocalUserManagementService implements UserManagementService {
  public void changeUserPassword(final Long userId, final String newPassword) {
    final User user = userRepository.get(userId);
    if(user != null) {
      user.changePassword(newPassword);
    }
  }
}

But now I have another problem, if the user is not found the method completes successfully and the user gets no feedback regarding the error. Therefore I need to either add a boolean return value indicating success of the operation or I can throw an exception, as in the following code.

public class LocalUserManagementService implements UserManagementService {
  public void changeUserPassword(final Long userId, final String newPassword) {
    final User user = userRepository.get(userId);
    if(user != null) {
      user.changePassword(newPassword);
    } else {
      throw new UserNotFoundException(userId);
    }
  }
}

This code is becoming less and less readable...

Throw an exception

Instead of checking for a null value and then throwing an exception, my preference is that the get method should throw a (runtime) exception such as a NoResultException or something more closely tied to your domain model. My reasoning for this is that it is the solution that allows me to write the least, and therefore most readable, code. Unlike the null solution I don't have to write any special code to handle this situation in the UserManagementService I can just leave it as it was originally.

Note that in both of these two solutions above we need to add some exception handling code to either the controller or spring's ExceptionMapper.

Null Object Pattern

One solution that was named during the discussion at work was the Null Object Pattern. Applying this pattern to this use case would mean that the get() method would return an instance of User where all methods were just stubs that do nothing.

A naïve implementation of the pattern would mean that the changeUserPassword() method would complete normally giving no feedback to the user. The solution to this would be to make changePassword() return a boolean value indicating success, but this has various problems, including an extra class to maintain and less obvioud feedback to the user (why did updating the password fail?).

Default value

Another solution proposed in the discussion was to modify the get method to get(userId, default) so that the caller gets to define the desired return value if nothing was found. Although this is a worthy solution, in the context of my use case there really is no default that would make sense. Which would bring us back to the Null solution.

Scala

Worth a mention here, while Scala does support null object references for compatibility with Java libraries, idiomatic Scala would use the Option class in this situation. The Scala language provides several interesting methods of handling the None value gracefully.

Summary

The subject of null references has always been the source of much discussion in the java world, this post just presents my view on things within a definite context. I hope someone can scrape something useful from this.

This Blog represents my personal views and experiences which are not necessarily the same as those of my employer.