I have been writing a custom JPA Query to handle a complicated query that may or may not return a result.
Note: I am using a simple query as an example for this question.
Example 1:
@Query(value = "SELECT TOP(1) e FROM Employee e WHERE e.NAME = :name", nativeQuery = true)
Employee getEmployeeByName(@Param("name") String employeeName);
Example 2:
@Query(value = "SELECT s FROM Student s WHERE s.CLASS = :class", nativeQuery = true)
List<Student> getStudentsByClass(@Param("class") String className);
In both these examples is it recommended to use Optional as a return type (as shown below), since there could be cases where either we don't get an Employee or Student?
@Query(value = "SELECT TOP(1) e FROM Employee e WHERE e.NAME = :name", nativeQuery = true)
Optional<Employee> getEmployeeByName(@Param("name") String employeeName);
@Query(value = "SELECT s FROM Student s WHERE s.CLASS = :class", nativeQuery = true)
Optional<List<Student>> getStudentsByClass(@Param("class") String className);
I have tried both the ways but just want to understand if this is one of the original use-case for introducing Optional.
CodePudding user response:
Optional
is a core Java class, so it was not introduced for anything to do with Spring or JPA, but the practical answer to your question is "yes." Spring/Hibernate/JPA support it for cases like your first example. It not only provides some convenient methods to act based on the presence or absence of a value (such as orElse()
), but also as a form of contract that clearly indicates the return can be null. Returning Optinal
makes it clear to callers that it's possible for the result to be empty/missing/absent - in other words, null
.
Having said that, returning Optional<List<>>
, as in your Example 2, doesn't make sense; a query method that returns a collection of objects would return an empty collection, not null
. So there's no need to use Optional
in that case.
CodePudding user response:
It is not required to use Optional
with List<T>
since Spring Data will return an empty list (zero size) if nothing found.
However, if you return a single object, it is possible that there will be no match and then you will get null
instead of object. And further you will possibly get NullPointerException
trying to invoke it's methods.
It's up to you to use Optional
with single object or don't. Because there may be situations depending on your business, if for example you're totally sure that desired object will be found (for example, some constants), then you may not use Optional
. But in cases when there is any chance that object may be not found, surely use Optional
and check if your actual object is present.
This is the typical approach.