Hibernate L1 cache + pessimistic_write lock question

It seems that hibernate returns a cached entity instance from its L1 cache as a result of select with PESSIMISTIC_WRITE lock.

Let’s imagine that we have a human with age 18 in the database and two following concurrent transactions are executed:

| * TRANSACTION:1                          | TRANSACTION:2
| * BEGIN                                  |
| * repository.findById(1)                 | BEGIN
| *                                        | human = repository.findById(1)  // human.hashCode() == 22, age is 18
| * human = repository.findByIdLocked(1)   | 
| *                                        | human = repository.findByIdLocked(1) // SELECT FOR UPDATE Query is executed
| * human.setAge(21)                       | blocked
| * COMMIT                                 | blocked
|                                          | // lock is released on DB, query returns row where age is 21, hibernate returns cached human instance obtained on first select
|                                          | human.hashCode() == 22 // true
|                                          | human.getAge() == 18 // true
|                                          | human.getAge() == 21 // false
↓ time

Is it supposed to be like this? Won’t it make sense to refresh the data in a cached version of entity as the DB call is executed in any case to acquire lock?

Sample project: GitHub - antalos/hibernate-test

This is a tough topic. I would argue that only EntityManager.refresh should actually update the state in existing entities, but I can see how it is desirable for EntityManager.find to do the same in this case. I don’t know what the JPA specification has to say about this case specifically, but if you think this is a violation or not according to the intent of the specification, let me know which sections suggests this.