0

Our scenario:

  1. JPA entity gets loaded (via Hibernate) and passed to the front-end (including the version of the entity).
  2. The user modifies the data and then (possibly a couple of minutes later), the modified entity data is sent from the front-end (FE) to the back-end (BE) (including ID and the version of the entity).
  3. On the BE, the corresponding entity is again loaded from the DB, updated with new values coming from FE (including version) and saved to the DB.

Problem: Optimistic locking (concurrent modification detection) doesn't work because the version attribute is modified in such a way that concurrent modification cannot be detected.

For example, an entity has version 100 at the time it is first loaded from the DB. While the entity data is being modified by Alice on the FE (say, for 30 minutes), the entity is modified five times by some automatic process and its version gets increased to 105. When Alice finishes its changes, the application sends the modified data to the BE. The BE loads the corresponding entity (now in version 105) from the DB and updates its attributes with values that came from the FE, including the version attribute. So the managed entity has been loaded with version 105 but the version was later explicitly changed to 100. Now, the BE calls EntityManager.merge(…) to save the data to the DB. Once the JPA flush is invoked, the version field gets increased and the data is saved to the DB.

The problem is that, during flush, the version is not increased to 101 (as I expect) but to 106.

Is this the correct behaviour? How can I make it work the intended way?

I have tested this with Hibernate 5.1.10 and 5.2.17.

  • I think best option here is at step 3,after loading the entity from DB,update new values from FE except version. – selman May 31 '18 at 08:33
  • The version entity should be managed by the DB layer code only. It is used to detect differences between the database and the backend layer. Front end should not know the version and modify it. All changes between load from DB to save should be a "by one" increment only. – Konrad May 31 '18 at 08:36
  • I think hibernate is doing the right thing. As your backend process loads data and works on it when the FE loaded data is waiting for user, the new version should be as it is happening. – Shafin Mahmud May 31 '18 at 08:36
  • @selman: It wouldn't make any difference in effect because Hibernate behaves exactly as if I made no changes to the version field. – Marián Petráš May 31 '18 at 08:47
  • @Konrad: As I understand your comment, our scenario as described in the post is not supported. – Marián Petráš May 31 '18 at 08:49
  • @MariánPetráš Ah OK. Then what is the issue?This is expected behaviour. – selman May 31 '18 at 09:04
  • @selman: The issue is that changes of the version field (made by an application) are ignored, as explained in [this answer](https://stackoverflow.com/questions/30881071/optimistic-locking-not-throwing-exception-when-manually-setting-version-field#30881238). – Marián Petráš May 31 '18 at 09:08

0 Answers0