@Modifying is used alongside @Query on repository methods to mark a query as a write operation -- an UPDATE or DELETE -- rather than a SELECT, telling Spring Data JPA to execute it differently and propagate its changes to the database.
Key Points: • Without @Modifying, Spring Data JPA assumes a @Query method returns query results and will not execute UPDATE/DELETE statements correctly. • @Modifying queries typically need to run inside a @Transactional context, since they alter data. • The method can return an int representing the number of rows affected, which is useful for confirming how many records were changed. • clearAutomatically = true on @Modifying clears the persistence context after the update, preventing stale, previously-loaded entities from shadowing the just-written database state.
Example: Bulk-deactivating all users who haven't logged in for a year is more efficient as a single UPDATE statement than loading every matching entity into memory and saving each one, so the repository method is annotated with both @Query and @Modifying.
Code Example:
public interface UserRepository extends JpaRepository<User, Long> {
@Modifying
@Transactional
@Query("UPDATE User u SET u.active = false WHERE u.lastLogin < :cutoff")
int deactivateInactiveUsers(@Param("cutoff") LocalDate cutoff);
}Interview Tip: A concise interview answer is:
"@Modifying marks a @Query method as a write operation, an UPDATE or DELETE, so Spring Data JPA executes it as a bulk statement instead of expecting a result set. I pair it with @Transactional, and often clearAutomatically = true, to avoid the persistence context holding stale entity state after the bulk change."