Lädt...

🔧 Try To Use `savepoint` In Spring JPA/Hibernate


Nachrichtenbereich: 🔧 Programmierung
🔗 Quelle: dev.to

This article describes my failed attempt to use the PostgreSQL SAVEPOINT in Spring JPA.
About PostgreSQL SAVEPOINT.

EntityManager

@PersistenceContext  
private EntityManager entityManager;

@Transactional(propagation=NESTED, isolation= READ_UNCOMMITTED)  
public void transferWithSavePoint(String fromAccount, String toAccount, String anotherAccount,  
                                  double amount) throws SQLException {  
    // step 1  
    Account from = accountRepository.findByName(fromAccount);  
    Branch fromBranch = branchRepository.findByName(from.getBranchName());  

    from.setBalance(from.getBalance().subtract(BigDecimal.valueOf(amount)));  
    fromBranch.setBalance(fromBranch.getBalance().subtract(BigDecimal.valueOf(amount)));  

    accountRepository.save(from);  
    branchRepository.save(fromBranch);  

    Connection connection = entityManager.unwrap(SessionImpl.class).connection();  
    Savepoint savepoint = connection.setSavepoint();  

    // step 2  
    Account to = accountRepository.findByName(toAccount);  
    Branch toBranch = branchRepository.findByName(to.getBranchName());  

    to.setBalance(to.getBalance().add(BigDecimal.valueOf(amount)));  
    toBranch.setBalance(toBranch.getBalance().add(BigDecimal.valueOf(amount)));  

    accountRepository.save(to);  
    branchRepository.save(toBranch);  

    connection.rollback(savepoint);  

    // final step  
    Account finalAccount = accountRepository.findByName(anotherAccount);  
    Branch finalBranch = branchRepository.findByName(to.getBranchName());  

    finalAccount.setBalance(finalAccount.getBalance().add(BigDecimal.valueOf(amount)));  
    finalBranch.setBalance(finalBranch.getBalance().add(BigDecimal.valueOf(amount)));  

    accountRepository.save(finalAccount);  
    branchRepository.save(finalBranch);  
}

I use Connection Pool in this project, so the connection created by EntityManager is different @Transactional method’s connection

Image description

  • savepoint: is before transferWithSavePoint
  • rollback: rollback to all of the operations before, so STEP1 is rollback, but STEP2 and Final STEP is done.

Next Try: AbstractTransactionStatus

@Autowired  
private JdbcTemplate jdbcTemplate;  

@Autowired  
private TransactionTemplate transactionTemplate;

public void transferWithSavePoint(String fromAccount, String toAccount, String anotherAccount,  
                                  double amount) {  
    transactionTemplate.execute(status -> {  
        Account from = accountRepository.findByName(fromAccount);  
        Branch fromBranch = branchRepository.findByName(from.getBranchName());  

        from.setBalance(from.getBalance().subtract(BigDecimal.valueOf(amount)));  
        fromBranch.setBalance(fromBranch.getBalance().subtract(BigDecimal.valueOf(amount)));  

        accountRepository.save(from);  
        branchRepository.save(fromBranch);  

        Object savepoint = status.createSavepoint();  

        // step 2  
        Account to = accountRepository.findByName(toAccount);  
        Branch toBranch = branchRepository.findByName(to.getBranchName());  

        to.setBalance(to.getBalance().add(BigDecimal.valueOf(amount)));  
        toBranch.setBalance(toBranch.getBalance().add(BigDecimal.valueOf(amount)));  

        accountRepository.save(to);  
        branchRepository.save(toBranch);  

        status.rollbackToSavepoint(savepoint);  

        // final step  
        Account finalAccount = accountRepository.findByName(anotherAccount);  
        Branch finalBranch = branchRepository.findByName(to.getBranchName());  

        finalAccount.setBalance(finalAccount.getBalance().add(BigDecimal.valueOf(amount)));  
        finalBranch.setBalance(finalBranch.getBalance().add(BigDecimal.valueOf(amount)));  

        accountRepository.save(finalAccount);  
        branchRepository.save(finalBranch);  

        status.releaseSavepoint(savepoint);  

        return null;    });  
}

Also failed:

JpaDialect does not support savepoints — check your JPA provider’s capabilities

Then I start to search ‘How to use savepoint in Hibernate’ online:

Please note that this is not a recommended way to use Spring JPA. It’s better to structure your transactions so that you don’t need to use savepoints or nested transactions. If you find yourself needing them, it might be a sign that your transactions are too complex and should be broken down into smaller parts.

Maybe I’m wrong from the beginning, indeed, I won’t encounter it in real application scenarios, but I’m just trying to figure out how to implement it, so let me know if you have any good ideas.

...

🔧 Try To Use `savepoint` In Spring JPA/Hibernate


📈 87.37 Punkte
🔧 Programmierung

🔧 Build CRUD RESTful API Using Spring Boot 3, Spring Data JPA, Hibernate, and MySQL Database


📈 52.91 Punkte
🔧 Programmierung

🔧 Understanding Database Connection Management in Spring Boot with Hibernate and Spring Data JPA


📈 52.91 Punkte
🔧 Programmierung

🔧 How To Integrate NCache With JPA Hibernate for Caching in Spring Boot Applications


📈 44.57 Punkte
🔧 Programmierung

🔧 hibernate-012: Which Direction to Use for Each Relationship Type in Hibernate?


📈 39.15 Punkte
🔧 Programmierung

🔧 Getting Started with Hibernate: An Introduction to ORM and JPA Annotations


📈 36.24 Punkte
🔧 Programmierung

🔧 Real Life Scenarios I: Avoiding Extra Scripts in Database Operations with JPA/Hibernate 👀


📈 36.24 Punkte
🔧 Programmierung

🔧 Paralelos entre Hibernate, JPA, Ruby e Rails


📈 36.24 Punkte
🔧 Programmierung

🔧 Java Hibernate vs JPA: Quick Review


📈 36.24 Punkte
🔧 Programmierung

🕵️ hibernate-core up to 5.4.23.Final JPA Criteria API sql injection


📈 36.24 Punkte
🕵️ Sicherheitslücken

🔧 hibernate-014: Why Did Hibernate Introduce Unidirectional and Bidirectional Relationships?


📈 35.43 Punkte
🔧 Programmierung

🔧 hibernate-011: Understanding Unidirectional vs. Bidirectional Relationships in Hibernate


📈 35.43 Punkte
🔧 Programmierung

🔧 hibernate-006: Unidirectional One-to-Many and Many-to-One in Hibernate (Department ↔ Employee)


📈 35.43 Punkte
🔧 Programmierung

🔧 Learn Spring Boot and Spring Data JPA


📈 35.19 Punkte
🔧 Programmierung

🎥 Spring Boot & Spring Data JPA – Complete Course


📈 35.19 Punkte
🎥 Video | Youtube

🔧 Upgrade Guide To Spring Boot 3.0 for Spring Data JPA and Querydsl


📈 35.19 Punkte
🔧 Programmierung

🔧 Connecting Spring Boot Applications to a Database with Spring Data JPA


📈 35.19 Punkte
🔧 Programmierung

🔧 Master REST API Development and Streamline Data Access with Spring Boot and Spring Data JPA


📈 35.19 Punkte
🔧 Programmierung

🔧 SavePoint best Explanation


📈 30.16 Punkte
🔧 Programmierung

🔧 SAVEPOINT in SQL


📈 30.16 Punkte
🔧 Programmierung

🔧 Transaction Control Language TCL - COMMIT, ROLLBACK, and SAVEPOINT


📈 30.16 Punkte
🔧 Programmierung

🔧 Advanced Query Techniques in Spring Data JPA


📈 26.86 Punkte
🔧 Programmierung

🔧 Advanced and Dynamic Searching With Spring Data JPA


📈 26.86 Punkte
🔧 Programmierung

🔧 Don't forget to flush! — Ensuring Data Integrity in Spring Data JPA


📈 26.86 Punkte
🔧 Programmierung

🔧 Spring Boot 3 JPA + Auth + JWT


📈 26.86 Punkte
🔧 Programmierung

🔧 Spring Data JPA Method Naming Conventions: Build Queries Without Writing SQL


📈 26.86 Punkte
🔧 Programmierung

🔧 Delving into Spring Data JPA: Mastering Mutual One-to-Many Dependencies


📈 26.86 Punkte
🔧 Programmierung

🔧 Insert into a jsonb Column in Spring Boot 3 + JPA + PostgreSQL


📈 26.86 Punkte
🔧 Programmierung

📰 heise+ | Einfachere Datenbankabfragen mit Spring Data JPA durchführen


📈 26.86 Punkte
📰 IT Nachrichten

🔧 Como iniciar um aplicativo Spring Boot + JPA + MySQL


📈 26.86 Punkte
🔧 Programmierung

matomo