javaspringhibernatejpaspring-data-jpa

JPA @Version annotation with @Query


Our entities has version field, which works fine with Spring Data JPA repository methods taking entity as an argument. However, for JPA modifying queries version doesn't get upgraded, why?

public class Foo {

  @Column(name = "VERSION")
  @Version
  private Long version;
}

public interface FooRepository extends JpaRepository<Foo, Long> {

  @Modifying
  @Query(value = "UPDATE Foo foo SET foo.bar = 'hello' WHERE foo.id = :id)")
  void updateFoo(@Param("id") Long id);
}

I would like for updateFoo-method to increment the version also (without adding it to query by hand).


Solution

  • @Modifying and @Version Related Situation:
    

    Automatic Update of Version Field: JPA automatically updates the field marked with @Version, but this is only done with standard operations such as find or save. If you are doing a manual update using @Modifying, you need to include the version information in the @Modifying query so that the version number is incremented.

    When Optimistic Locking is Wanted: If you are doing an UPDATE query using @Modifying, you may need to update the version number yourself.

    Here is an example of how to manage the version field when performing an UPDATE with @Modifying:
    
    
    public interface FooRepository extends JpaRepository<Foo, Long> {
    
      @Modifying
      @Query(value = "UPDATE Foo foo SET foo.bar = 'hello' foo.version = foo.version + 1 WHERE foo.id = :id)")
      void updateFoo(@Param("id") Long id);
    }
    

    The version value is updated manually (i.e. we increase the version number by 1 with each UPDATE operation).

    At the same time, we compare it with the current version value in the WHERE condition to provide optimistic locking. If the version value does not match (i.e. another operation has changed the version number), this operation will not be executed and an OptimisticLockException error will be thrown.