What is the cleanest way to return a Hibernate unique result when it might be null
?
Is there anything wrong with this solution:
public Category getCategoryById(int id) {
Object result = currentSession.createCriteria(Category.class)...uniqueResult();
return (Category) result;
}
And is there a better way to do this?
There is no clean way to do this, as it depends on your API.
If you express that your method could return null
, especially in the JavaDoc - possibly supported by a @Nullable
, nothing is wrong to return null
here.
I usually do that, if I expect that the requested value does not exist in some valid state in my application:
/**
* Tries to find a category by its id.
*
* @param id the id
* @return the category for that id or {@code null} if not found
*/
@Nullable
public Category findCategoryById(int id) {
Object result = ....uniqueResult();
return (Category) result;
}
On the other hand you can throw an exception if an missing element would be invalid and document that as well:
/**
* Resolve a category by its id.
*
* @param id the id as given by another method
* @return the category for that id
* @throws NoSuchElementException if the element does not exist
*/
@Nonnull
public Category getCategoryById(int id) {
Object result = ....uniqueResult();
if (result == null) {
throw new NoSuchElementException("category for id: " + id);
}
return (Category) result;
}
(I have to admit that I'm using the annotations only on occasions)
I'm using different method names (findCategoryById
v.s. getCategoryById
) for both situations. If you stick to a naming scheme, the users of your API will know what to expect without reading the JavaDoc.
In Java 8 and Google Guava there is a combination of both solutions: Optional
/**
* Finds a category by its id.
*
* @param id the id
* @return the category for that id, an empty value if not found
*/
public Optional<Category> findCategoryById(int id) {
Object result = ....uniqueResult();
return Optional.ofNullable((Category) result);
}
The advantage here is, that the caller can decide if he expects the value to exist or not:
// The value must exist, otherwise a NoSuchElementException is thrown:
...findCategoryById(id).get();
// The value could be null:
...findCategoryById(id).orElse(defaultValue);
The biggest problem is, that many Java developers are not used to it up to now, but I guess that will improve in time...
Additional reading material
There is a community wiki as well for some (or more) points about the caller side of the when to check for null problem: Avoiding != null statements
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