I'm working on a weird issue, I was doing integration testing, calling my controller to get an object from database that doesn't exist.
public Optional<T> get(Long id) { try { return Optional.ofNullable(repository.getOne(id)); } catch(EntityNotFoundException e) { return Optional.empty(); } }
When getOne(…)
is not able to find anything, I was expecting an EntityNotFoundException
but actually nothing. If I inspect my result I can see that I have an empty entity with a handler link to it "threw EntityNotFoundException
" but we don't go in the catch and I return an optional of this weird entity.
I can't understand this behavior.
It is not thread safe by default, thus it needs to be managed (read: correctly bound to a thread and proxied to point to the thread-bound instance).
These Repositories are Java interfaces that allow you as the developer to define a data access contract. The Spring Data JPA framework can then inspect that contract, and automatically build the interface implementation under the covers for you.
Crud Repository doesn't provide methods for implementing pagination and sorting. JpaRepository ties your repositories to the JPA persistence technology so it should be avoided. We should use CrudRepository or PagingAndSortingRepository depending on whether you need sorting and paging or not.
This is due to the way JPA specifies EntityManager.getReference(…)
to work. It's supposed to return a proxy that will either resolve the object to be returned on the first access of a property or throw the contained exception eventually.
The easiest way to work around this is to simply use findOne(…)
instead, like this Optional.ofNullable(repository.findOne(…))
. findOne(…)
will return null
in case no result is found.
A more advanced way of resolving this is to make the repository return Optional
instances directly. This can be achieved by creating a custom base repository interface using Optional<T>
as return type for the find…
-methods.
interface BaseRepository<T, ID extends Serializable> extends Repository<T, ID> { Optional<T> findOne(ID id); // declare additional methods if needed } interface YourRepository extends BaseRepository<DomainClass, Long> { … }
Find a complete example of this in the Spring Data examples repository.
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