Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I was looking for an answer to the question of what a DAO should return when a search ends up to be for an entity that does not exist.

There are some generic previous questions related to returning null, but I am looking for an answer specifically in the context of the DAO retrieve scenario.



To be clear, when I say Null Object I am referring to the Null Object pattern. In the Java space, Josh Bloch recommends an empty collection solution in the book Effective Java (See Item 43) which provides an very good introduction to the problem/solution.


Despite being aware of Bloch's advice when I first wrote this question I considered returning null appropriate in a read/retrieval scenario. I'm in good company making a mistake with nulls.

share|improve this question
2  
What's wrong with your question is that it is very hard to decipher what you are asking. It seems almost a request for a discussion, for which P.SE isn't the right place. –  Bart van Ingen Schenau May 14 '13 at 17:25
    
+1 Good question - lots of solutions, like exceptions, returning null, etc. –  Brandon May 14 '13 at 17:28
2  
For some background, Null References - the Billion Dollar Mistake. –  MichaelT May 14 '13 at 18:00
2  
@Crowie: I have reformulated your question, so it makes a better fit for this site. The question itself was fine, it was just formulated in a non-constructive way. –  Bart van Ingen Schenau May 14 '13 at 18:00
    
@Brandon: I would use an exception to indicate an error, not a valid empty result (which is what Crowie seems to have in mind). –  Giorgio Jan 13 at 9:53

4 Answers 4

up vote 7 down vote accepted

In "Effective Java" item 43 p. 201, Joshua Bloch says, "There is no reason ever to return null from an array- or collection-valued method." He recommends returning a zero-length array or an empty collection (Collections.emptyXxx) when there are legitimately no results. For one thing, it's a pain for the client to double-check everything:

if ( (retVal == null) || (retVal.size() < 1) ) {
    ...
}

Before returning null, ask yourself if the null return value is a result of a programming error on the part of the calling code. Such a check is generally done in the first few lines of a procedure as a defensive check for invalid input values and could legitimately result in throwing an unchecked exception instead of returning null. For my reasoning on this, please see the Checked vs. Unchecked Exceptions entry in my blog.

Scala and Haskell avoid returning null with an Option class. I don't immediately see how this is better than null (other than being type-safe just for the sake of it), but I thought I should mention it as another point of view:

val nameMaybe = request getParameter "name"
nameMaybe match {
  case Some(name) =>
    println(name.trim.toUppercase)
  case None =>
    println("No name value")
}

Bloch suggests that null is an appropriate return instead of an empty collection in C because array lengths are stored separately from arrays and there is no advantage to allocating an empty array. But a null is not the right answer all the time in all languages.

share|improve this answer
1  
What if there is nothing to return? i.e. calling a method on a service to get the stock ticker price for a stock that does not exist. What would be returned then? –  Mike May 14 '13 at 17:36
4  
@Crowie: Page 201 in the 2nd ed., Item #43: "Return empty arrays or collections, not nulls". He speaks about not returning null when you would have otherwise returned an array/collection. –  FrustratedWithFormsDesigner May 14 '13 at 17:44
3  
C++ shouldn't differ from Java in this regard, as the answer should be the same for all sufficiently compatible languages: null is only acceptable if the function in question can only return zero or one object. Otherwise, an empty collection clearly indicates that nothing was retrieved. –  Bart van Ingen Schenau May 14 '13 at 18:06
1  
@Crowie: Ok, but why not? If the user of your code can determine if nothing was found simply by testing resultSet.getLength()==0, why return null instead? Maybe you'd rather throw a NoDataFound exception? But I don't think finding nothing when attempting to read from a database is really exceptional (in general). –  FrustratedWithFormsDesigner May 14 '13 at 18:09
8  
The Option (or Maybe) type is not 'being type-safe just for the sake of it'. 1) It forces you to always consider an empty result. 2) It allows you to compose functions, returning null on the first failure. It can make your code considerably shorter and clearer. –  lortabac Jan 13 at 9:01

A search suggests that there will be multiple results which is an easy case - always return a collection. If there are no results, then the collection will simply have no items.

If there can be 0 or 1 result, it depends on the semantics of the search. Can there only be a 1 result because you are artificially limiting the search results to 1? I would go with a collection with 0 or 1 items, the limit could probably change at some point.

If there can truly only be 0 or 1 result, you are probably trying to "search" by an unique identifier or such. In normal application usage, this "search" will never fail. It is not really a search. Your application doesn't generate links with invalid ids or whatever.

However, in exceptional situations such as:

  • A page with links has been loaded and been sitting idle for a while. Some of the resources behind the links have been deleted in the meanwhile. Now when you click such a link, the "search" would fail.
  • The user manually "circumvents" the application and uses the address bar directly to enter arbitrary id numbers.
  • ...

All of the above are exceptions. So it is very easy, throw an exception. Probably a NotFoundException that doesn't need to be caught anywhere that can just bubble to the top for an automatic 404 error page.

share|improve this answer

Don't return null - Use the Null Object Pattern


In contrast to my prior answer, I've later concluded that yes, applying the Null Object Pattern, or Josh Bloch's advice to never return null (as detailed in Glen Patterson's answer above) does apply to DAOs.

For me, the puzzle about this question was that if I'm searching for a record, even if I dislike doing so, why wouldn't I return null to indicate nothing was found.

"There might be nothing there, so just return null"


On a DAO, why not return null if there is nothing there?

Well, in the same vein why in particular return null if something is not there? Null doesn't inherently mean something. It doesn't naturally indicate if the object or entity, exists or does not exist. Further, I don't think the users of your interface/DAO/API should need to know what null does mean. To me, null doesn't clearly indicate what occurred. A service layer or some other higher layer might be more appropriate in asking if any exist, or handling if none exist. A type might indicate nothing. But null doesn't necessarily indicate nothing.

In the context of this question about DAOs, why should returning null generally mean that a record was not found when you can return something that clearly indicates one was found or not.


What about if something unexpected happened?

Returning null still doesn't necessarily help and an exception would seem appropriate in this case. If it's appropriate why not throw and handle an exception. Returning null doesn't need to be associated with something unexpected. If you return null you are conceptually mapping null to errors and the user of your API will need to learn that.




Searching for objects returning Collections, as a way of implementing Null Object Pattern

If you want to find something with your DAO, say with a method like follows

public SomeSearchedType find(long id) { .... }

.... why not just search for objects that exist and return a collection, like this....

public List<SomeSearchedType> find(long id) { .... }

... and let your service layer, or some higher layer handle it? While the first object may also return null, the second object allows for a simple, and easy to understand collection.size() check.


Or....

Say you don't buy that. Well, in the context of DAOs, why? Having your DAO return null and not a collection makes it less flexible, and without making the code anymore expressive. Or another way of looking at the problem of null, if you really want to know if zero were returned, why not make your usage of the DAO indicate that i.e. maybe put some syntactical sugar in your service layer or maybe get your DAO to check for quantities. But then, maybe use Null Object Pattern... but in the end why make it return null?

Although I seem to have hastily read of Josh Bloch's instruction, or am at least trying to be practical, I saw his instruction as

"If you're going to use null have a bl***y good reason"

Reading over time has made me think that a good reason needs to be solid. In this case I've concluded that there is no reason to make my DAO users expect null and no reason why I or they can't accommodate this in a better way than requires null.

share|improve this answer

With regard to should methods return null or an empty object, this question has been answered by kronoz.

Returning null is usually the best idea if you intend to indicate that no data is available.

An empty object implies data has been returned, whereas returning null clearly indicates that nothing has been returned.

Additionally, returning a null will result in a null exception if you attempt to access members in the object, which can be useful for highlighting buggy code - attempting to access a member of nothing makes no sense. Accessing members of an empty object will not fail meaning bugs can go undiscovered.

I think his sums it up - return null, and as the comments their follow on with that the method should be documented that it returns null.

Documenting returning null is important because I like it to be clear why a method would return null if it returns null at all.

share|improve this answer
1  
As you described, there's already a good general answer to this question, and you don't address the DAO retrieve scenario. –  Mike Partridge May 14 '13 at 17:47

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.