I have an endpoint that looks like this:
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteScooter(@PathVariable long id) {
boolean isDeleted = scootersRepository.deleteById(id);
if (!isDeleted) throw new ResourceNotFoundException("The scooter could not be found with id: " + id);
return ResponseEntity.ok().build();
}
And the relevant deleteById method:
@Transactional
@Override
public boolean deleteById(long id) {
boolean isDeleted = false;
try {
Scooter scooterRef = entityManager.getReference(Scooter.class, id);
System.out.println(scooterRef); // <--- this line here
entityManager.remove(scooterRef);
isDeleted = true;
} catch (Exception e) {
// no-op
}
return isDeleted;
}
If I leave the code like it is shown above and make a call to the delete endpoint passing in an unknown id
this will throw a resourceNotFoundException
(expected behaviour, all good so far)
But if I remove this specific line from the deleteById method:
System.out.println(scooterRef); // <--- this line here
An internalServerErrorException
is thrown instead.
My question is, what exactly is this println
invocation doing? And is there a cleaner solution to execute the expected behaviour of this code without using a println
?
UPDATE:
The expected behaviour also occurs if I remove the println
and try to access one of the attributes inside the reference, like so:
// System.out.println(scooterRef);
scooterRef.getMileage(); // <-- ResourceNotFoundException is thrown, good
Now I do vaguely remember that in some cases you need to access the referenced object in some way (e.g. by calling an attribute) to make it load completely or something like that, but I dont remember the exact reasoning anymore.
You can try using entityManager.find(Scooter.class, id)
;
However from what this blog explains even though getReference
only returns a proxy object, for deletion it should work exactly the same.