๐Ÿ”ด The Error You're Seeing

Confirm this matches your console output. If it does, you're in the right place.

ERROR LOG2026-03-01 09:15:22.410 ERROR 8842 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: javax.persistence.TransactionRequiredException: Executing an update/delete query] with root cause javax.persistence.TransactionRequiredException: Executing an update/delete query at org.hibernate.query.sql.internal.NativeQueryImpl.doExecuteUpdate(NativeQueryImpl.java:309)

โšก Quick Fix Works 80% of the time

Add @Transactional and @Modifying annotations to your repository or service method.

@Transactional @Modifying @Query("UPDATE User u SET u.status = :status") void updateStatus(@Param("status") String status);

๐Ÿง  Why this Happens

Tap to expand the deep technical explanation

JPA and Hibernate strictly enforce that any operation modifying the database (INSERT, UPDATE, DELETE) must occur within a transaction. If you attempt to execute a modifying query without an active transaction context, Hibernate throws this exception to prevent silent, uncommittable data changes.

The HITEC City Parking Spot Analogy:

Imagine trying to withdraw money from a bank account, but the bank hasn't opened the vault yet. The teller (Hibernate) refuses to process the transaction because the secure environment (Transaction) isn't established.

๐Ÿ” How to Reproduce Confirm this is your error

Call an @Modifying repository method (an update/delete JPQL query) from a service method without @Transactional. Hibernate throws TransactionRequiredException: Executing an update/delete query.

๐Ÿ› ๏ธ Solutions (3 Ways to Fix)

Solution 1โœ“ Most common cause

Add @Transactional to the method

๐Ÿ‘‰ Use this when executing UPDATE or DELETE JPQL/SQL queries.

Hibernate requires an active database transaction to modify data. Without @Transactional, Spring doesn't open a transaction, and Hibernate rejects the query.

@Service public class UserService { @Transactional // Add this public void updateStatus(Long id, String status) { userRepository.updateStatus(id, status); } }
Solution 2

Add @Modifying to the Repository

๐Ÿ‘‰ Use this if you are using a custom @Query for UPDATE/DELETE in your Spring Data JPA repository.

Spring Data JPA needs to know that your @Query alters data so it can execute it correctly. @Modifying tells Spring to treat it as an update operation.

@Repository public interface UserRepository extends JpaRepository<User, Long> { @Modifying @Transactional @Query("DELETE FROM User u WHERE u.active = false") void deleteInactiveUsers(); }
Solution 3

Check for proxy bypass (Self-Invocation)

๐Ÿ‘‰ Use this if you added @Transactional but it still throws the error.

If you call a @Transactional method from another method in the SAME class, Spring's AOP proxy is bypassed, and the transaction is never started. Move the method to a different bean.

// BAD: Called from same class, @Transactional ignored public void batchUpdate() { this.updateOne(); // Proxy bypassed! } // GOOD: Inject the bean into itself @Autowired private UserService self; public void batchUpdate() { self.updateOne(); }

๐Ÿ“‹ Version Notes

Spring Boot 2.x

Uses javax.persistence.TransactionRequiredException.

Spring Boot 3.x

Uses jakarta.persistence.TransactionRequiredException.

๐Ÿ›ก๏ธ How to Prevent This Next Time

Always annotate service methods that modify data with @Transactional. Use @Modifying on custom Spring Data JPA update/delete queries.

Course Search
Search across all chapters & stages
๐Ÿ“–

Search the course

Type any topic โ€” branching, stash, rebase, hooks โ€” and jump straight to that chapter.

merge branchesgit stashundo commitrebase