I have a question related to correct handling of returns of the DAO library I'm writing for one project. This library probably is going to be used by another people, and I want to do it correctly. How I should deal with return statements of the functions of my DAO?
Example 1 I have function to getCustomer which should return String. In case a query doesn't return any result should I return null, an empty string or throw some kind of exception?
Example 2
I have a function, getCutomerList
, which returns a value of type ArrayList<String>. In case a query doesn't return any result should I return null, an empty ArrayList or throw some exception?
Example 3
Some SQL exception was detected, what should I do, throw exception or do try
..catch
of the block where it can occur?
What is the "good" practice or "best" practice to apply in my case?
It seems your library is doing database-like calls. If that is the case, then I would do exactly what is implemented by the JPA 2 specification.
What I mean by that is, look at the find()
method in JPA API and return exactly what they are doing there.
/**
* Find by primary key.
* @param entityClass
* @param primaryKey
* @return the found entity instance or null
* if the entity does not exist
* @throws IllegalStateException if this EntityManager has been closed.
* @throws IllegalArgumentException if the first argument does
* not denote an entity type or the second
* argument is not a valid type for that
* entity's primary key
*/
public <T> T find(Class<T> entityClass, Object primaryKey);
You see here in find
, which I think is similar to your getCustomer()
method, it will return null
if none is found, and only throwing IllegalArgumentException
if the argument is invalid.
If the find()
method is not close to what you want with getCustomer()
you should implement the same behavior as getSingleResult():
/**
* Execute a SELECT query that returns a single result.
* @return the result
* @throws EntityNotFoundException if there is no result
* @throws NonUniqueResultException if more than one result
* @throws IllegalStateException if called for a Java
* Persistence query language UPDATE or DELETE statement
*/
public Object getSingleResult();
Which will throw EntityNotFoundException
if no result is found, NonUniqueResultException
if multiple instances are found or IllegalStateException
if the SQL is wrong.
You have to decide which behavior is most suitable for you.
The same goes for getResultList():
/**
* Execute a SELECT query and return the query results
* as a List.
* @return a list of the results
* @throws IllegalStateException if called for a Java
* Persistence query language UPDATE or DELETE statement
*/
public List getResultList();
getResultList()
will return null if none is found and only throwing exception if the SQL is illegal.
By following this behaviour, you are being consistent, and your users will get a feeling of knowing how the library is.
An alternate behavior is to return an empty collection instead of null
. This is how Google Guava have implemented their API, and which is really the preferred why. However, I like consistency, and still think you should implement the library as close to the standard
as possible.
Joshua Bloch made a video explaining how to design a good API and why it matters.
getCustomer()
should return Customer. If it returns String it should be probably called getCustomerName()
or getCustomerId()
Example 1: Since nothing is retrieved, null should be returned. Alternatively, Null-Object pattern can be a choice.
Example 2: Prefer empty ArrayList to null. See "Effective Java" Item 43: Return empty arrays or collections, not nulls
Example 3: Translate the SQLException to higher Exception and throw it. See "Effective Java" Item 61: Throw exceptions appropriate to the abstract
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With