JPA findBy method always goes to orElseThrow
return specRepo.findByIdentificationType(idType)
.orElse(specRepo.findById(idType)
.orElseThrow(() -> new ResourceNotFoundException("...")));
Is the reason.
Java is quite eager in execution and always calls the orElse method to prepare just in case it would need it.
The order of your execution is somehow:
specRepo.findByIdentificationType(idType)
orElse
cannot be executed as it's argument is not evaluated yetspecRepo.findById(idType)
.orElseThrow(() -> new ResourceNotFoundException("..."))
- The result of 3 and 4 becomes an object
o
orElse(o)
Instead of using orElse
one should prefer orElseGet
.
return specRepo.findByIdentificationType(idType)
.orElseGet(() -> specRepo.findById(idType)
.orElseThrow(() -> new ResourceNotFoundException("...")));
It will only be called when needed.
We have two scenarios here:
specRepo
returns an non-empty Optional.specRepo
returns empty object.
In scenario 1, idType
is a valid identificationType
thus is not an id
, so the findById
will throw an exception.
In scenario 2, idType
is not a valid identificationType
and if it is a legal id
the method should result in exception being thrown.
Edit:
While this answers diagnoses the problem and describes what is the reason of such behavior, @Abinash Ghosh
answer provides the simplest and imo best solution of the problem.
In general, avoid using orElse
. In this case, add the findByIdentificationTypeOrId(String it, String id)
to your repository.
@xenteros is right that is the problem.
You can use findByIdentificationTypeOrId
to get data in one query
return specRepo.findByIdentifcationTypeOrId(idType, idType)
.orElseThrow(() -> new ResourceNotFoundException("...")));
and repository like
@Repository
public interface IdentificationSpecRepository extends CrudRepository<IdentificationMaster, String>{
Optional<IdentificationMaster> findByIdentificationTypeOrId(String identificationType, String id);
}