Reputation: 331
Should I always use the Optional to check null in Java 8?
And is it a good practice that I use it in my DAO layer? Here's a snippet code of my DAO layer:
public Optional<Tag> retrieveTagByValue(String tagValue) {
Tag tag = null;
try {
tag = em.createNamedQuery("Tag.findByValue", Tag.class)
.setParameter("tagValue", tagValue)
.getSingleResult();
} catch (NoResultException e) {
System.out.println(e.getMessage());
}
return Optional.ofNullable(tag);
}
Because in my Service layer, I want to know whether the tag is null or not, if it is null then I create a new tag. So I am wondering should I use Optional in this case, is there any better ways to improve this method? Thanks a lot!
Upvotes: 2
Views: 1012
Reputation: 120858
I want to know whether the tag is null or not
than this is the perfect case to use Optional. And you got your explanations about how to refactor your code, but think about the caller of this method.
You are being very explicit that this method might return a result that is not present - expressed via Optional.empty
or a result that might be present, expressed via Optional.get/isPresent
etc. This way you force the caller to make some decisions based on whether the results in present or not. That is simply not the case when returning a reference.
Upvotes: 1
Reputation: 91
Should I always use the Optional to check null in Java 8?
If a method would return null
in Java 7 and lower then you should use Optional.empty()
in Java 8. Using Optional
helps you to get rid of null
checks and makes code easier to read. Optional
is although used in streams.
I would rewrite the code in the following manner:
public Optional<Tag> retrieveTagByValue(String tagValue) {
try {
Tag tag = em.createNamedQuery("Tag.findByValue", Tag.class)
.setParameter("tagValue", tagValue)
.getSingleResult();
return Optional.of(tag);
} catch (NoResultException e) {
return Optional.empty();
}
}
It's not considered to be a good practice to use System.out...
for logging, you should use some logging library instead.
And is it a good practice that I use it in my DAO layer?
Personally, I would replace DAO with repository (check out Spring Data) and I would use Optional
in Service layer instead.
Upvotes: 2
Reputation: 298233
I’d call your example an anti-pattern unnecessarily introducing null
, regardless of how your perform the subsequent null
-check.
Consider:
public Optional<Tag> retrieveTagByValue(String tagValue) {
try {
Tag tag = em.createNamedQuery("Tag.findByValue", Tag.class)
.setParameter("tagValue", tagValue)
.getSingleResult();
return Optional.of(tag);
} catch (NoResultException e) {
System.out.println(e.getMessage());
return Optional.empty();
}
}
This way, we’re not using Optional
to perform a null
check, we’re using it to not introduce a null
in the first place.
It’s still debatable whether it is an improvement for the caller, to get an empty Optional
in the erroneous case and having to loop-back and parse the standard output to find out the actual reason, compared to catching a meaningful exception.
But if not having a result is considered to be within the normal operation of this method (compare with Stream.findAny()
), returning an empty Optional
is fine, but then, it shouldn’t be necessary to print a message to System.out
.
Upvotes: 4