0

I have a problem related to an Update JPQL Query. After I run the query I am not getting the updated row values by providing JPA read APIs. And to me, this seems to be a Cache-related issue in JPA.

Oiriginal JPA Repository

public interface WalletRepository extends JpaRepository<Wallet, Integer> {

    Wallet findByWalletId(Integer id);

    @Modifying
    @Transactional
    @Query("UPDATE Wallet w SET w.amount = :amount WHERE w.walletId = :walletId")
    void updateWalletAmount(@Param("amount") Double newWalletAmount, @Param("walletId") Integer walletId);
}

Let's say I have a row in Wallet {walletId = 1, amount = 500}

After I run the below sequence of code

updateWalletAmount(300, 1);
Wallet wallet = walletRepository.findByWalletId(1);
System.out.println(wallet.getAmount()); 
// Print: 500, It should print : 300

Things I tries and researched

So I found a similar question which is talking about similar problem and the solution mentioned there is using flushAutomatically and clearAutomatically with @Modifying annotation and what it will basically do is force Entity manager to write all the dirty entity changes to DB and then clear the persistence cache. So I run find API again, entity will have updated values from DB. Yor can check the question here : Spring Boot Data JPA - Modifying update query - Refresh persistence context

The problem with this approach is that, I don't want any of the DB changes in a transaction to be reflected in DB if at any point throughout the lifetime of the Transaction anything goes wrong with DB reads and writes. So if a transaction fails, I want all the changes to be cleared without writting them in DB. But in this approach I am already forcing the changes to be flussed in DB at the time of update. And if later transaction fails, those changes are already in DB.

Expectations

I would like to know if there is a way in JPA where I can update the values of entities such that it updates in the persistence context and do not flus changes in DB until Transaction is complete?

  • Flushing is not directly related to commits. Open a transaction, write queries and then rollback will result in no changes outside of that transaction. As you‘re in a transaction you see the changes, but you‘ll have to reload an entity to get the updated values from the DB. – Martin Frey Jul 23 '23 at 10:02

0 Answers0