get()
method which throws when entity is not found
#5855
Replies: 4 comments 5 replies
-
Note that fortunately we don't have this problem in |
Beta Was this translation helpful? Give feedback.
-
IMO we should go with The fact that it throws Just calling |
Beta Was this translation helpful? Give feedback.
-
How about we try aligning the naming with the existing |
Beta Was this translation helpful? Give feedback.
-
OK, so perhaps I need to give a better example of the sort of thing I want to write: try {
Book book = session.get(Book.class, id);
book.blahBlahBlah();
// .... lots of stuff
}
catch (EntityNotFoundException e) {
// this catch might even be a couple of frames up the stack!
reportToUser();
} These are bad alternatives: try {
Book book = session.getOptional(Foo.class,id).orElseThrow()
book.blahBlahBlah();
// .... lots of stuff
}
catch (NoSuchElementException e) {
// this catch might even be a couple of frames up the stack!
reportToUser();
} Verbose, and try {
Book book = session.getOptional(Foo.class,id).orElseThrow(() -> new EntityNotFoundException("message", id))
book.blahBlahBlah();
// .... lots of stuff
}
catch (NoSuchElementException e) {
// this catch might even be a couple of frames up the stack!
reportToUser();
} Is absurdly verbose. I would rather just write The point is that I want to make correct null handling automatic, something users get with almost no work, not something they have to jump through hoops to do. FTR, I'm not implacably opposed to adding a |
Beta Was this translation helpful? Give feedback.
-
This is an issue that has been bothering me for a while (a couple of years), though the time to deal with it was not really ripe. This is an ancient error I made many years ago, and which was copied by the JPA spec. Nobody really seems to have ever drawn attention to it in all these years.
The problem is this:
Session.get()
andEntityManager.find()
returnnull
if there is no matching row. Therefore, almost every single call to either of these methods should be followed by an immediatenull
check. I very much doubt that this is actually done in a disciplined way in most programs that use Hibernate. And that makes these programs rather vulnerable to NPEs.And an NPE really is a significantly worse thing to deal with than a
NoResultException
, which can in principle be handled much further up the call stack and reported in a sensible way. NPEs are bugs; aNoResultException
doesn't have to be.Therefore, I think we need to rectify this ancient mistake by adding a new method to
Session
. The main problem is that all the good names are already taken: we've already usedget()
,find()
, andload()
. So what would we call this?getOrThrow()
is pretty clear and explicit but a bit ugly.retrieve()
is available but unlovely.load()
is already deprecated in H6, we could in principle come back in a couple of releases or so and undeprecate it, but change its semantics to eager rather than lazy loading ... this is actually a suprisingly clean solution, since it's just the semantics that this method should always have had, and from a very strict point of view it can be argued that it's a non-breaking change. You just get the error a bit earlier, though it will be a different kind of error, and recoverable. There's no need to change the signature ofload()
in any way, AFAICS. And I think it's a good name that is suggestive of the difference in semantics.For completeness I'll mention that
session.getOptional(Foo.class,id).orElseThrow()
looks like it sorta does what I want, though in a verbose way. But it doesn't really solve the problem sinceNoSuchElementException
is almost as bad asNullPointerException
. Another reason to keep dislikingOptional
.Of the above options I think I would lean towards waiting for a bit, and then undeprecating
load()
.Thoughts? Any good alternative names?
Beta Was this translation helpful? Give feedback.
All reactions