0

Entity Class : Sport

import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Version; import java.util.UUID; @Entity public class Sport { @Id private UUID id; private String name; private String description; @Version private Long version; // getter and setter omitted } 

I have one IT named as RepositoryIT with one Test case :

 @Rollback(value = false) @Test public void validate_version_increment(){ // GIVEN final Sport sport = new Sport().setId(UUID.randomUUID()).setDescription("Cricket").setName("Cricket"); final Sport sport1 = sportRepository.save(sport); // as per my understanding version should be 0 sport1.setDescription("Awesome"); final Sport sport2 = sportRepository.save(sport1); // as per my understanding version should be 1 sport2.setDescription("Too many rules for beginners"); final Sport sport3 = sportRepository.save(sport2); // now version should be 2 ? or not1 sport3.setDescription("Too many1 rules for beginners"); final Sport sport4 = sportRepository.save(sport3); sport4.setDescription("Too many2 rules for beginners"); final Sport sport5 = sportRepository.save(sport4); sport5.setDescription("Too many3 rules for experts"); sportRepository.save(sport5); } 

version is always 1 but it does update description. After saving sport1 version increments to 1 and then it does not care.

and this is the hibernate logs :

Hibernate: insert into sport (description, name, version, id) values (?, ?, ?, ?) 2020-12-04 20:23:19.350 DEBUG 13961 --- [ main] n.t.d.l.l.SLF4JQueryLoggingListener : Name:DS-Proxy, Connection:3, Time:3, Success:True, Type:Prepared, Batch:False, QuerySize:1, BatchSize:0, Query:["insert into sport (description, name, version, id) values (?, ?, ?, ?)"], Params:[(Cricket,Cricket,0,86aad234-6493-413d-83c1-89927be91948)] Hibernate: update sport set description=?, name=?, version=? where id=? and version=? 2020-12-04 20:23:19.353 DEBUG 13961 --- [ main] n.t.d.l.l.SLF4JQueryLoggingListener : Name:DS-Proxy, Connection:3, Time:1, Success:True, Type:Prepared, Batch:False, QuerySize:1, BatchSize:0, Query:["update sport set description=?, name=?, version=? where id=? and version=?"], Params:[(Too many3 rules for experts,Cricket,1,86aad234-6493-413d-83c1-89927be91948,0)] 

I can not understand, what is the rule of @Version increment ? I know Hibernate Dirty check will check for changes for managed entity and I am changing something in every update but maybe save() does not play any role and after only transaction ends on commit it increases the version.

2 Answers 2

1

The rule, first and foremost, is to only flush changes to the DB when necessary. Since it's a transactional method, you can make as many changes as you like, and until the changes actually make it into the DB when the transaction is committed, the version will not be incremented.

The version increment you are seeing is due to the final value being committed being different than the one originally fetched. The intermediate changes you make just make the original fetched entity dirty, but they don't make it to the DB, so - no version update.

Debug your test and you'll see that sport1, sport2 etc. all point to the same Java object. Also, no update statements happen until the transaction is committed. save only marks the entity as being tracked by JPA, it doesn't immediately issue any DB inserts/updates.

Sign up to request clarification or add additional context in comments.

Comments

0

As it is a transaction, commit is happening after return statement. Changes are persisted in database while committing the transaction in this case. As you are not flushing explicitly, changes reflect in database only after commit. And before commit operation you are mapping the current state of entity.

Solution 1 : You can use flush explicitly

final Sport sport5 = sportRepository.saveAndFlush(sport4); 

Solution 2 : You can commit your entity once the transaction is performed

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.