Persistence Layer return convention issue and question - null vs. exception
I'm writing a position paper on persistence layer query returns. It deals with querying for a single object or a collection of objects and what to do if the object or collection of objects are not found in the database. I've googled many different search terms and have not come up with any authoritative references for this scenario. Do any of you know of any sources that have discussed this before?
My current logic is that when searching for a single object in a persistence layer that the persistence layer should return a simple null if the object isn't found.If searching for a collection of objects then the PL should return an empty collection object.
1.
/** Returns a list of objects that match the non-null fields in the provided example object.
This will return an empty Collection if no matching objects are found */
public Collection retrieveByExample(MyBO example);
2./** Returns a business object. This will return a null if no matching object is found */
public MyBusObject retrieveById(int aMyBusObjectId);
These two methods would not return a "checked or unchecked" exception if the object(s) are not found. I think that they are the simplest to implement and do not break the convention of not using exceptions in non exceptional situations. I don't feel that it is the persistence layer's responsibility to make a business decision on an object's existence being an exception. There are many times where applications search for an object to see if it exists or not and then proceed to create the object or use the object if it exists or doesn't. These two methods also don't force using application layers to catch or throw any declared exceptions.
Notes on scenario 1: program control flow is simple by using an iterator and hasNext(), if the collection is empty then any code that needs the objects can be skipped.
Notes on scenario 2: program control flow is simple in this case with a " != null or == null check. If the method returned an uninitialized object instead of null then the calling application would have to have additional business logic to tell whether the object was truly uninitialized or not. I can see the method having a UnexpectedMultipleBusinessObjectsFoundException if more than 1 object is found since the method is looking by primary key, but would this ever happen if searching by primary key. However in a similiar method that searches on non primary key then the UMBOFE would be warrented. Any thoughts?
Others have brought up some additional scenarios.
3./** Returns one and only one business object from persistence with a matching primary id.
If one and only one match is not found, null is returned if isLenient is true, otherwise an exception is thrown. */
public MyBusObject retrieveById(int aMyBusObjectId,boolean isLenient)throws BusinessObjectNotFoundException;
I feel this option is bad in that it forces the calling or using application layer to still declare the BusinessObjectNotFoundException.It adds bulk and unneeded complexity to the the code.
While looking at it I can see that since a caller is searching for exactly 1 object then if the query finds more than one object then a UnexpectedMultipleBusinessObjectsFoundException could be thrown. But I don't believe an NotFoundException is warranted. What are your thoughts?
Message was edited by:
smalltalk

