From reading the official documentation on the CrudRepository interface, I see that the findById method returns an Optional. I understand why - there might be no database record for the id being searched so it makes sense to use the Optional class to avoid NullPointerExceptions. Almost all of the tutorials on the Spring Boot Data JPA package show you how to write custom queries, like here for example. But none of these tutorials feature an example where a custom method returns an Optional. If I'm writing a Repository and I'm writing custom queries, shouldn't they also return Optionals seeing as the principle set down by findById would indicate that this is best practice?
EDIT: I just came across this blog post that outlines good reasons for not returning Optionals in a Repository but I'd be interested to read what the folks on here think.
The author's point about finding a record by ID is one to think about, because depending on how the rest of your application is written, a missing record might indicate a programming mistake (such as forgetting to start a transaction). I don't fully agree with it though, because there are probably some cases where it's possible to look for a specific record because an ID was handed to the application in a request. Some people say it's a bad idea to make your IDs externally visible, but I haven't seen any good alternatives to let clients identify specific records. I particularly find the following bit grating:
You provide a list of data (maybe a result of a search) and you provide a detail view on a single entry. So, you show the list in your UI and on a click on of the elements, the details of ID XYZ-123 are shown. This set of data must be there!
The author conveniently seems to forget that web applications are used by multiple clients concurrently, and the database may change between requests.
The rest of the article is nonsense. The bit about "postponing the problem to the caller" is exactly the point. How should a repository know what to do when a certain record is missing? It shouldn't throw an exception, because maybe it's an expected situation that the caller can deal with. It shouldn't return null because returning null doesn't force the caller to think about what they should do if a record is missing. It's also a good idea to use Optional outside of functional programming. It's simple: If there is a possibility that a method can return empty-handed, return Optional.