From the JPA specification , section 3.4.2 :
An entity can access the state of its version field or property, or export the method to be used by the application to access the version, but must not change the version value. Except as specified in Section 4.10, only a persistence provider is allowed to set or update the version attribute value in an object.
The purpose of the version property is to protect us from simultaneous updates that may occur after the object is loaded in the current persistence context, and Hibernate implements it, ignoring any value that you set manually, but rather uses the value obtained from the database when loading the object . To verify this, enable the printing of the values ββof the associated variables, and you will also notice that the value from the database is being used.
For example, the standard solution, which is used in practice when working with DTO, must perform a manual check when updating the state of an object from the DTO:
if (entity.getVersion() != dto.getVersion()) { throw new OptimisticLockException("..."); }
Of course, you can make this more general by going from the base class, which provides this check for all entities supported by versions or in some sort of recycling method. For example, some authors do this directly in the version editor:
public void setVersion(long version) { if (this.version != version) { throw new OptimisticLockException("..."); } }
Hibernate automatically performs this check for individual objects, as can be seen from the implementation of DefaultMergeEventListener :
else if (isVersionChanged(entity, source, persister, target)) { if (source.getFactory().getStatistics().isStatisticsEnabled()) { source.getFactory().getStatisticsImplementor() .optimisticFailure(entityName); } throw new StaleObjectStateException(entityName, id); }
Dragan bozanovic
source share