2

Whenever implementing data modifying logic using Query annotation (insert, update or delete) in JpaRepository, both @Transactional (not necessarily on the repository method) and @Modifying have to be used.

My understanding is as follows. All crud operations provided by JpaRepository are transactional unless we overwrite them. When implementing a method in a repository, we need to make sure it's still transactional. It can be achieved simply by annotating with @Transactional. The default value of readOnly is false, hence spring "knows" it's a modifying query.

The question is: why do we need @Modifying annotation then (together with @Transactional)? Maybe I'm missing something?

I'm aware of the discussions like this or that, but I'm missing an explicit explanation for why @Modifying has to be used if @Transactional carries all the information needed.

Andronicus
  • 25,419
  • 17
  • 47
  • 88

1 Answers1

3

From the reference docs

By default, CRUD methods on repository instances are transactional. For read operations, the transaction configuration readOnly flag is set to true. All others are configured with a plain @Transactional so that default transaction configuration applies.

and @Modifying answers the question why do we need @Modifying annotation then?

Indicates a query method should be considered as modifying query as that changes the way it needs to be executed. This annotation is only considered if used on query methods defined through a Query annotation). It's not applied on custom implementation methods or queries derived from the method name as they already have control over the underlying data access APIs or specify if they are modifying by their name.

Queries that require a @Modifying annotation include INSERT, UPDATE, DELETE, and DDL statements.

also

The @Modifying annotation is only relevant in combination with the @Query annotation. Derived query methods or custom methods do not require this Annotation.

(together with @Transactional)

@Transactional is not required along with @Modifying. It is just that the method annotated with @Modifying should execute within a transaction.

R.G
  • 6,436
  • 3
  • 19
  • 28
  • _"@Transactional(readOnly=true) can call a repository method annotated with @Modifying"_ as far as I'm aware only on data sources that don't support read-only transactions, otherwise execution will fail. – Mark Rotteveel Feb 21 '20 at 10:30
  • @MarkRotteveel I admit that I am not aware of that . I tested this on an in-memory h2 database. If the example is wrong I will edit that out – R.G Feb 21 '20 at 10:37
  • It looks like H2 doesn't have read-only transactions (eg see [SpringFramework: @Transactional(readOnly = true) not working with h2](https://stackoverflow.com/questions/44499137/springframework-transactionalreadonly-true-not-working-with-h2)) – Mark Rotteveel Feb 21 '20 at 10:41
  • Thank you . I will modify the answer – R.G Feb 21 '20 at 10:44