Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to return a unique result from Hibernate when it may be null?

Tags:

java

hibernate

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?

like image 793
mad_fox Avatar asked Oct 18 '22 21:10

mad_fox


1 Answers

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

like image 161
Tobias Liefke Avatar answered Nov 01 '22 12:11

Tobias Liefke