springjpaspring-data-jpaspring-data

How to dynamically set lock in JPA


I have below simple example. I want the JPA method findByName to dynamically set lock. In the changeUserNames method I want it set a lock. In getUsers method I don't want it to set lock. How can I achieve this?

public interface UserRepository extends JpaRepository<User, String> {

   @Lock(LockModeType.PESSIMISTIC_WRITE)
   List<User> findByName(String name);
}


public class UserService {

   @Autowired
   private UserRepository userRepository;

   @Transactional
   public void changeUserNames() {
      List<User> users = userRepository.findByName("name1");  // I want this findByName use set PESSIMISTIC_WRITE lock
      users.forEach((user) -> {
          user.setName("name2");
          userRepository.save(user);
      });
   }


   public List<User> getUsers() {
      return userRepository.findByName("name1"); // I want this findByName to not set any lock
   }
}

Solution

  • Define two repository methods:

    List<User> findByName(String name);
    
    @Lock(LockModeType.PESSIMISTIC_WRITE)
    List<User> findForUpdateByName(String name);
    

    Inside the getUsers method, invoke the findByName method.

    Inside the changeUserNames method, invoke the findForUpdateByName method.