| Question 2 is a bit harder to tackle because it is related to a different issue which I believe to be a Hibernate bug - but I have not yet been able to reproduce it outside of a production database scenario:
2) If you need the entity to be locked, why not refresh using: em.refresh( customer, LockModeType.PESSIMISTIC_WRITE ); This is precisely what I was doing up until a couple of months ago (except utilizing the Hibernate session object directly). However, this caused a very odd bug to occur within a production environment. I had two entities with a @OneToMany association between them (Let's call them Parent and Child). Executing a loop such as parent.getChildren().forEach(...) would cause a LazyInitializationException to occur. Typically this is easy to resolve - either your session has been closed or the entity is detached. However, I can safely say neither of those were the case in this system (I never detach entities nor is the session closed until commit time). The basic flow which caused the LazyInitializationException was something like this:
1. Read in entity
2. Perform some logic which delazifies children
3. Refresh entity with NO_WAIT lock (which succeeds)
4. Flushes occur
5. Invoke method to iterate over children
The key takeaway there was that for some reason, the flush after the refresh with lock was causing the collection to become detached even though the entity itself was not. I could literally delazify the collection prior to a specific flush - but not after without causing the LazyInitializationException. If this sounds familiar to you and has already been fixed then awesome! If nothing has been reported about this, then I most certainly understand that is nowhere near enough information to log a bug against which I will happily do when I have managed to isolate the behavior to a more simple test case. So, ultimately, I am unable to modify my code to go back to the refresh(entity, lockOptions) API without reintroducing that issue, but I can not avoid refreshing entities after locking them due to this issue. If I could rely on Hibernate to provide the current lock mode correctly - then at least I could skip extraneous lock invocations/refreshes when possible. |