We're updating the issue view to help you get more done. 

Lost Update caused by optimistic lock excluded attributes

Description

We originally discovered this issue with Hibernate 4.3.10 but could reproduce it on 5.2.10 as well.
Basic description
If an attribute that is excluded from optimistic locking is updated the update may reset the value of other attributes which are not excluded from optimistic locking. For this to occur two major factors play a role. First factor is that an entity has base class with InheritanceType.JOINED which declares a version attribute for optimistic locking. The second factor is that the optimistic lock excluded attribute and the attribute suffering the lost update are both declared on the same entity inheriting from that base class.
If one transaction updates an attribute not excluded from optimistic locking with a concurrent transaction updating the attribute which is excluded from optimistic locking the value of the value of the not excluded attribute is reset if the concurrent transaction finishes later.

We tried to set org.hibernate.annotations.DynamicUpdate on the entity class which is affected as a Workaround, but this only solves part of the issue. After enabling dynamic updates on the entity class the lost update was solved, but the entity cache returned an entity with the problematic state.

Steps to reproduce

  1. unzip attached reproducer

  2. run "mvn test" in the context of the unpacked directory

Further notes
The issue seems to occur in this combination because if the version attribute were declared on the same table as the other attributes hibernate issues the update statement with a check for the version attribute. If the version attribute has changed meanwhile the second update on the lock excluded attribute would not change any data and the stale object state would be reported via an exception. With joined inheritance the check in the where clause is absent and thus the data is updated and the stale object state is not recognized.
Without optimistic lock exclusion, the second transaction would actively check the version in the table of the base class and recognize the concurrent modification.
The changed behavior after applying dynamic updates is caused by the fact that the reset of the optimistic lock included attribute results from the flush of all attrbutes independent of them having changed.

Environment

None

Status

Assignee

Unassigned

Reporter

Aaron Schmischke

Fix versions

None

Labels

None

backPortable

Backport?

Suitable for new contributors

None

Requires Release Note

None

Pull Request

None

backportDecision

None

Components

Affects versions

5.2.10
4.3.10

Priority

Critical