Most Java developers use @Transactional, but as developers, it’s important to understand its internal working, especially for frequently used features. Today topic is @Transactional Annotation 1)what is @Transactional annotation? Ans: @Transactional is a key feature in the Spring Framework that provides declarative transaction management. It ensures that a group of database operations are executed as a single unit of work. If all operations complete successfully, the transaction is committed; if any operation fails, the entire transaction is rolled back. 2)Internal working of @Transactional annotation? Ans: When we use @Transactional, Spring creates a proxy for the bean using AOP. When the transactional method is called, the call goes through this proxy. The proxy has a transaction interceptor, which starts the transaction before calling the actual method. After the method execution, based on the outcome interceptor will commit or rollback the transaction. Business logic runs in the original method, but the transaction boundaries are controlled by the proxy. 3)Scenarios @Transaction annotation not working? Ans: Self-invocation : Calling a transactional method from the same class (proxy is bypassed) Private / static / final methods : Proxy cannot apply transaction on these methods Object not managed by Spring : If we create object using new, transaction won’t work Checked exceptions : By default, rollback will not happen for checked exceptions Exception handled internally : If we catch exception and don’t rethrow, rollback won’t happen Any things i miss here please add in comment. #java #spring #learning #development #springboot #microservices #kafka #hibernate #jpa
Understanding Spring's @Transactional Annotation for Java Developers
More Relevant Posts
-
Most Java developers write this code every day. And don't realize it's making 50 database calls instead of 1. 🧵 It looks completely fine: List<Orders> orders = orderRepository.findAll(); for (Order order : orders) { System.out.println(order.getUser().getName()); } Clean. Readable. Innocent. But here's what's actually happening behind the scenes: 👉 1 query to fetch all orders 👉 1 query PER order to fetch the user 50 orders = 51 queries. 500 orders = 501 queries. This is the N+1 problem. And it silently kills performance. I hit this exact issue in my project. API response was creeping from 300ms to 2+ seconds. No errors. Nothing in logs. Just slow. Profiled it. Found 51 database calls for a simple list fetch. The fix was 1 line: @Query("SELECT o FROM Order o JOIN FETCH o.user") List<Order> findAllWithUser(); Result: 2100ms → 290ms ⚡ Why does this happen? JPA's default fetch type is LAZY — it waits until you access the relationship to query it. Inside a loop, that means one query per iteration. JOIN FETCH tells Hibernate — get everything in one query. The rule I follow now: If you're looping through entities and accessing relationships — always check your query count first. One annotation. Massive difference. Have you run into N+1 in your project? 👇 #Java #SpringBoot #Hibernate #JPA #BackendDevelopment #JavaDeveloper #SoftwareEngineering
To view or add a comment, sign in
-
-
🚨 Exception Handling in Java: More Than Just try-catch Many developers treat exception handling as an afterthought. But in reality, it's one of the pillars of building robust and maintainable systems. Good exception handling is not about catching everything — it's about handling the right things, in the right way. 💡 Key principles every Java developer should follow: ✔️ Catch only what you can handle If you don’t know how to recover, don’t swallow the exception. Let it propagate. ✔️ Never ignore exceptions An empty catch block is a hidden bug waiting to explode in production. ✔️ Use specific exceptions Avoid generic Exception or Throwable. Be explicit — it improves readability and debugging. ✔️ Add context to exceptions Wrap exceptions with meaningful messages: throw new OrderProcessingException("Failed to process order " + orderId, e); ✔️ Use finally or try-with-resources Prevent resource leaks: try (BufferedReader br = new BufferedReader(new FileReader(file))) { // use resource } ✔️ Create custom exceptions when needed They make your domain logic clearer and more expressive. ⚠️ Common anti-patterns: ❌ Swallowing exceptions ❌ Logging and rethrowing without context ❌ Using exceptions for flow control ❌ Catching NullPointerException instead of fixing the root cause 🔥 Pro tip: Well-designed exception handling turns unexpected failures into controlled behavior — and that’s what separates fragile systems from resilient ones. How do you usually handle exceptions in your projects? Have you ever debugged a production issue caused by bad exception handling? #Java #SoftwareEngineering #CleanCode #BackendDevelopment #BestPractices
To view or add a comment, sign in
-
-
10 Mistakes Java Developers Still Make in Production Writing Java code is easy. Writing Java code that survives production traffic is a different skill. Here are 10 mistakes I still see in real systems. 1. Using the wrong collection for the workload Example: - LinkedList for frequent reads - CopyOnWriteArrayList for heavy writes Wrong collection choice silently kills performance. 2. Ignoring N+1 query issues Everything looks fine in local. Production becomes slow because one API triggers hundreds of DB queries. 3. No timeout on external calls One slow downstream API can block request threads and take down the whole service. 4. Large @Transactional methods Putting too much logic inside one transaction increases lock time, DB contention, and rollback risk. 5. Blocking inside async flows Using @Async or WebFlux but still calling blocking DB/API code defeats the whole purpose. 6. Treating logs as observability Logs alone are not enough. Without metrics, tracing, and correlation IDs, debugging production becomes guesswork. 7. Thread pool misconfiguration Too many threads = context switching Too few threads = request backlog Both can hurt latency badly. 8. Bad cache strategy Caching without TTL, invalidation, or size control creates stale data and memory problems. 9. Not designing for failure No retries, no circuit breaker, no fallback. Everything works... until one dependency slows down. 10. Optimizing without measuring Most performance “fixes” are guesses. Always profile first. Then optimize. Final Thought Most production issues don’t come from advanced problems. They come from basic decisions made at the wrong place. #Java #SpringBoot #Microservices #BackendEngineering #Performance #SystemDesign #SoftwareEngineering
To view or add a comment, sign in
-
🚀 Java Streams Practice – Group Strings by Length Grouping elements is one of the most powerful features of Java Streams. Here’s a simple example of how to group a list of strings based on their length using Collectors.groupingBy() 👇 💻 Code Example: import java.util.*; import java.util.stream.Collectors; public class Main { public static void main(String[] args) { List<String> words = Arrays.asList( "Java", "Spring", "API", "Docker", "SQL", "AWS", "React" ); Map<Integer, List<String>> result = words.stream() .collect(Collectors.groupingBy(String::length)); System.out.println(result); } } 📌 Output: {3=[API, SQL, AWS], 4=[Java], 5=[Docker, React], 6=[Spring]} 🔍 Explanation: ✔ stream() → Converts list into stream ✔ groupingBy() → Groups elements by given condition ✔ String::length → Uses word length as grouping key 💡 This approach is very useful in real-world applications for categorizing and organizing data efficiently. #Java #JavaStreams #Coding #Programming #Developers #BackendDevelopment #SpringBoot #SoftwareEngineering #CodingInterview
To view or add a comment, sign in
-
🚀Stream API in Java - Basics Every Developer Should Know When I started using Stream API, I realized how much cleaner and more readable Java code can become. 👉Stream API is used to process collections of data in a functional and declarative way. 💡What is a Stream? A stream is a sequence of elements that support operations like: ->filtering ->mapping ->sorting ->reducing 💠Basic Example List<String> list = Arrays.asList("Java", "Python", "Javascript", "C++"); list.stream().filter(lang-> lang.startsWith("J")) .forEach(System.out : : println); 👉 outputs :Java, Javascript 💠Common Stream Operations ☑️filter() -> selects elements ☑️map() -> transforms data ☑️sorted() -> sorts elements ☑️forEach() -> iterates over elements ☑️collect() -> converts stream back to collection 💠Basic Stream Pipeline A typical stream works in 3 steps: 1. Source -> collection 2. Intermediate Operations -> filter, map 3. Terminal operation -> forEach, collect ⚡Why Stream API? . Reduces boilerplate code . Improves readability . Encourages functional programming . Makes data processing easier ⚠️Important Points to remember . Streams don't store data, they process it . Streams are consumed once . Operations are lazy (executed only when needed) And Lastly streams API may seem confusing at first, but with practice it becomes a go-to tool for working with collections. #Java #StreamAPI #JavaDeveloper #Programming #SoftwareEngineering #BackendDevelopment #LearningInPublic
To view or add a comment, sign in
-
-
Discover the differences between Stack and Heap in Java: how memory is allocated, managed, and used for variables, objects, and method calls.
To view or add a comment, sign in
-
Built DTOForge, a small Spring Boot tool that generates Java DTOs from JSON. Useful when integrating external APIs and you do not want to keep writing DTOs by hand. Supports: * Java records * Java classes * nested objects * arrays * optional Jackson annotations Source: `https://lnkd.in/eWEpUxPY Medium article: https://lnkd.in/eDmK-eVx #Java #SpringBoot #OpenSource #BackendDevelopment #APIIntegration
To view or add a comment, sign in
-
#Java #Wrapper #Class Why we need Wrapper Class in Java ? 👉 Wrapper classes = convert primitive → object Examples: int → Integer, char → Character, double → Double ✅ Main Reasons (Simple Points) 1. 📦 Use in Collections Java collections like ArrayList, HashMap work with objects only ❌ Cannot use int ✅ Use Integer 👉 Example: ArrayList<Integer> list = new ArrayList<>(); 2. 🔄 Conversion (Primitive ↔ Object) Convert data easily int → Integer (Autoboxing) Integer → int (Unboxing) 3. 🧰 Utility Methods Wrapper classes provide useful methods 👉 Example: Integer.parseInt("123"); Double.valueOf("10.5"); 4. ❌ Handle Null Values Primitive cannot store null Wrapper can store null 5. 💾 Required in Frameworks Many frameworks (like Spring, Hibernate) need objects Wrapper classes are required
To view or add a comment, sign in
-
The Command Pattern in Java: Eliminating Fat Service Classes with Commands and Handlers Fat Service classes are a liability — one class that does everything is a class that's impossible to test and dangerous to change. This post shows how to apply the Command pattern in Java using Records, Repository interfaces, and single-responsibility Handlers to keep your business logic clean and isolated....
To view or add a comment, sign in
-
The Command Pattern in Java: Eliminating Fat Service Classes with Commands and Handlers Fat Service classes are a liability — one class that does everything is a class that's impossible to test and dangerous to change. This post shows how to apply the Command pattern in Java using Records, Repository interfaces, and single-responsibility Handlers to keep your business logic clean and isolated....
To view or add a comment, sign in
Explore content categories
- Career
- Productivity
- Finance
- Soft Skills & Emotional Intelligence
- Project Management
- Education
- Technology
- Leadership
- Ecommerce
- User Experience
- Recruitment & HR
- Customer Experience
- Real Estate
- Marketing
- Sales
- Retail & Merchandising
- Science
- Supply Chain Management
- Future Of Work
- Consulting
- Writing
- Economics
- Artificial Intelligence
- Employee Experience
- Workplace Trends
- Fundraising
- Networking
- Corporate Social Responsibility
- Negotiation
- Communication
- Engineering
- Hospitality & Tourism
- Business Strategy
- Change Management
- Organizational Culture
- Design
- Innovation
- Event Planning
- Training & Development