Hidden N+1 in Spring Boot endpoint This endpoint runs 78 SQL queries… for a single request. And no one noticed. During a performance review, I analyzed a simple API: @GetMapping("/owners") public List<OwnerDto> getOwners() { return ownerRepository.findAll().stream() .map(owner -> new OwnerDto( owner.getId(), owner.getLastName(), owner.getPets().size() // ⚠️ hidden query )) .toList(); } Looks clean. Looks harmless. 🚨 What actually happens 1 query → fetch owners +1 query per owner → fetch pets 👉 With 77 owners: 1 + 77 = 78 SQL queries 💥 Real impact (measured) up to 1.2s per request ~29s cumulative DB time massive DB load under traffic ⚠️ Why this is hard to spot code looks clean no errors works fine in dev explodes only with real data ✅ Fix @EntityGraph(attributePaths = "pets") List<Owner> findAll(); 👉 Single query instead of dozens. 🧠 Takeaway Most performance issues are not in your code. They are in your data access patterns. 🔍 Bonus I built a small tool that detects this automatically: 👉 https://www.joptimize.io/ It highlights: N+1 queries slow endpoints hidden database overhead Are you sure your endpoints are not doing 10x more queries than expected? #JavaDev #SpringBoot #Hibernate #JavaPerformance #Backend #SoftwareEngineering
JOptimize’s Post
More Relevant Posts
-
Your DTO might be triggering database queries This looks like a clean DTO. But it can silently hit your database. public record User(String name, List<Order> orders) {} 🧠 Somewhere in your code user.orders().size(); 🚨 What actually happens 👉 Depending on your JPA setup: triggers a lazy query or loads the full collection or causes N+1 issues 👉 all from a simple .size() 💥 Real impact hidden database calls unpredictable performance harder to debug in production ✅ Better approach public record UserDto(String name, int orderCount) {} 👉 and compute it at the query level: SELECT u.name, COUNT(o) FROM User u LEFT JOIN u.orders o GROUP BY u.name 🧠 Takeaway A DTO should not control when your database is queried. 🔍 Bonus I built a tool that detects issues like: N+1 queries lazy loading traps inefficient data access 👉 https://joptimize.io How many hidden queries are behind your DTOs? #JavaDev #SpringBoot #Hibernate #JavaPerformance #Backend
To view or add a comment, sign in
-
If you're using Java records with Spring Data JDBC, you've probably written this: new Meetup(null, title, date) That null shows up everywhere you create a new entity. Callers shouldn't have to know how the id gets populated. A static factory method fixes it. The canonical constructor still exists, so Spring Data JDBC can materialize rows from the database. Your application code just stops dealing with null. It's the same pattern you already use in the JDK: List.of, Map.of, LocalDate.of. Thinking about turning this into a video. Would it be useful?
To view or add a comment, sign in
-
-
💡 𝐒𝐩𝐫𝐢𝐧𝐠 𝐃𝐚𝐭𝐚 𝐄𝐧𝐯𝐞𝐫𝐬 - 𝐚𝐮𝐝𝐢𝐭𝐢𝐧𝐠 𝐰𝐢𝐭𝐡𝐨𝐮𝐭 𝐭𝐡𝐞 𝐨𝐯𝐞𝐫𝐡𝐞𝐚𝐝 👉 Spring Data Envers adds automatic change tracking for your entities. ⚙️ Built on top of Hibernate Envers and seamlessly integrates with Spring Data JPA. ⁉️ What it gives you: ✔️ Full history of entity changes ✔️ Who changed what and when ✔️ Access to any previous state ✔️ Built-in versioning (revisions) ⚡ Minimal setup: @Entity @Audited public class User { @Id private Long id; private String name; } ➡️ Every change = new revision stored automatically 🚀 Use it when: ▪️ Audit logs (finance, security) ▪️ Versioning / history tracking ▪️ Rollbacks to previous states ▪️ User activity tracking 📌 Clean, reliable way to add auditing without reinventing the wheel. #SpringBoot #Java #BackendDevelopment #SoftwareEngineering #ProgrammingTips
To view or add a comment, sign in
-
-
Ever wondered what really happens when a JSON request hits a Spring Boot application? Here’s a quick, simplified journey ➡️ 1. Incoming Request (JSON) A client sends a JSON payload over HTTP. This request lands on the embedded server (usually Tomcat). ➡️ 2. Tomcat Thread Handling Tomcat assigns a thread from its pool to handle the request — this ensures multiple users can be served concurrently. ➡️ 3. Filters (Pre-processing) Before reaching your application logic, the request passes through filters (e.g., logging, CORS, security checks). ➡️ 4. DispatcherServlet (The Traffic Controller) Spring’s DispatcherServlet takes over — it’s the central hub that routes requests to the right components. ➡️ 5. Authentication & Security If security is enabled, Spring Security intercepts the request, validates tokens/credentials, and decides access. ➡️ 6. Handler Mapping DispatcherServlet finds the correct controller method based on URL, HTTP method, and annotations. ➡️ 7. JSON → Java Object (Jackson Magic) The request body is converted into a Java object using Jackson (via HttpMessageConverters). ➡️ 8. Controller Execution Your controller method runs with the mapped object and business logic kicks in. ➡️ 9. Response Flow Back The response object is converted back to JSON and sent through the same chain (in reverse). 💡 In short: JSON → Tomcat Thread → Filters → DispatcherServlet → Security → Controller Mapping → Object Conversion → Business Logic → Response Clean, structured, and highly extensible — that’s the beauty of Spring Boot. #SpringBoot #Java #BackendDevelopment #SoftwareEngineering #WebDevelopment #KSAJobs #RiyadhJobs #OpenToWork
To view or add a comment, sign in
-
Ever spent hours chasing down a performance issue in your Spring application, only to realize it’s the classic N+1 problem? For anyone who hasn’t encountered it yet, it typically appears when you fetch a list of entities, and then Hibernate executes an additional query for each related entity. Instead of a single efficient query, you end up with N+1 queries hitting your database.Everything may look fine in development, but under real traffic, the impact becomes obvious. I recently ran into this with a simple parent-child relationship. The code looked clean and straightforward, but once I enabled SQL logging, it became clear that multiple unnecessary queries were being executed behind the scenes. What helped me address it:1- Enabling SQL logs to see what was really happening.2- Using JOIN FETCH in JPQL where appropriate3- Applying @EntityGraph for better control over fetching.4- Being more intentional about lazy versus eager loading. The main takeaway for me was that ORMs simplify development, but they don’t remove the need to understand how queries are executed. #Spring #Springboot #JPA #ORM #Database
To view or add a comment, sign in
-
-
🚀 JDBC Driver Types – Complete Overview JDBC drivers are used to connect Java applications with databases. They implement the JDBC API and allow sending SQL queries and receiving results from the database. 🔹 What is JDBC Driver? ✔ Implements JDBC API interfaces ✔ Enables database connectivity in Java ✔ Sends SQL queries & retrieves results 👉 Explained clearly on page 1 🔹 Types of JDBC Drivers ✔ Divided into 4 types based on architecture ✔ Each type differs in performance & usage 👉 Classification shown on page 2 🔹 Type 1 – JDBC-ODBC Bridge ✔ Uses ODBC driver to connect database ✔ Requires DSN configuration ✔ Mostly outdated, used for learning 👉 Diagram on page 3 shows bridge flow 🔹 Type 2 – Native API Driver ✔ Converts JDBC calls into native DB calls (C/C++) ✔ Requires vendor-specific libraries ✔ Installed on client machine 👉 Architecture explained on page 3 🔹 Type 3 – Network Protocol Driver ✔ Uses middleware server ✔ Converts calls into DB-specific protocol ✔ Supports multiple databases 👉 Three-tier architecture shown on page 4 🔹 Type 4 – Thin Driver (Pure Java) ✔ Direct communication with database ✔ No external dependency required ✔ Best performance & most widely used 👉 Highlighted on page 5 🔹 Which Driver to Use? ✔ Single DB → Use Type 4 ✔ Multiple DBs → Use Type 3 ✔ If others unavailable → Use Type 2 👉 Recommendation given on page 6 💡 Type 4 (Thin Driver) is the most preferred choice due to high performance, flexibility, and ease of use #Java #JDBC #Database #Programming #Backend #JavaDeveloper #SoftwareDevelopment #AshokIT
To view or add a comment, sign in
-
The Spring Boot annotation that is silently corrupting your database. If you are a Spring Boot developer, you probably use @Transactional every day. If something fails, the database rolls back. Simple, right? But what happens when you write code like this? @Service public class UserService { // The entry point called by the Controller public void registerUser(UserDTO dto) { // ... some validation logic ... saveUserAndSendEmail(dto); } @Transactional public void saveUserAndSendEmail(UserDTO dto) { userRepository.save(new User(dto.email())); emailService.sendWelcomeEmail(dto.email()); // What if this throws an exception? } } What you think happens: If the email service fails and throws an exception, @Transactional catches it, rolls back the database insert, and the user is not saved. What ACTUALLY happens: The database commits the user anyway. Your system now has a user who never got their welcome email, and your database is in an inconsistent state. Why did it fail? The "Proxy Bypass" Trap. Spring’s @Transactional doesn't work by magic; it works by creating an AOP Proxy around your class. When an outside class (like your Controller) calls your Service, it hits the Proxy first, which opens the database transaction. BUT... if you call a method from within the same class (like registerUser calling saveUserAndSendEmail), you are using the internal this reference. You completely bypassed the Spring Proxy. The transaction never started. The rollback will never happen. The Senior Fixes: 1. The Architecture Fix: Move the @Transactional logic to a separate UserRegistrationService. Calling an external class forces you to go through the proxy. 2. The Simple Fix: Put @Transactional on the entry-point method (registerUser) instead of the internal helper method. Stop assuming annotations are magic. If you don't understand how proxies work under the hood, your data is at risk! Have you ever spent hours debugging a @Transactional rollback that just wouldn't trigger? 👇 #Java #SpringBoot #Hibernate #BackendDevelopment #Microservices #SoftwareEngineering #CleanCode #TechTips #LogicLedaMagic
To view or add a comment, sign in
-
Fetching a multi-level hierarchy from a relational database is a classic performance bottleneck. If you do it wrong, you end up with the dreaded N+1 query problem or a Cartesian product that brings your application to its knees. In this session, Java Champion Vlad Mihalcea delves into the most efficient strategies for retrieving complex data structures—specifically for scenarios where you need to store the result set in a cache like Redis. Join us: luma.com/6wrxlqj3
To view or add a comment, sign in
-
🎥 Project Demo: Java JDBC Login & Registration System Following up on my previous post where I shared screenshots of this project, I’m now sharing a short demo video showcasing its functionality in action. 🔧 Tech Stack: Java | JDBC | MySQL 🚀 Key Features: ✔ User Registration with persistent database storage ✔ Login Authentication using email & password validation ✔ Menu-driven console-based application ✔ Secure SQL execution using PreparedStatement ✔ Data integrity with unique email constraint 🔄 Workflow Demonstrated in Video: 1️⃣ User registers → Data stored in MySQL 2️⃣ User logs in → Credentials validated 3️⃣ System responds with success or failure message 🚀 Next Step: Converting this console-based system into a dynamic web application using JSP and Servlets. 💬 Feedback and suggestions are welcome! #Java #JDBC #MySQL #BackendDevelopment #Projects #Learning #SoftwareDevelopment
To view or add a comment, sign in
-
Just finished a project built purely with Java Servlets & JSP — no Spring, no shortcuts. Built a full Item Management System from scratch, and here's what went into it: Tech Stack • Java Servlets (MVC architecture) • Oracle Database with JDBC • JNDI DataSource for connection pooling • JSP for the view layer • Tomcat server Core Features • Full CRUD operations for items (add, update, soft-delete, list) • Item Details management — attach descriptions, issue dates, and expiry dates to any item • User authentication — signup, login, logout with session management and cookie-based persistence • Duplicate name validation and change detection before updating • Soft delete pattern to preserve data integrity Architecture Highlights • Clean separation of concerns: Controller → Service Interface → Service Implementation • Centralized action routing in a single servlet using a switch-case dispatcher • DataSource injected via @Resource annotation — no hardcoded credentials • Proper resource cleanup with a closeResources() helper in every service Building this from scratch without a framework like Spring was a great exercise in understanding what frameworks actually do for you under the hood. Always valuable to go back to the fundamentals. 🔗 GitHub:https://lnkd.in/dgdBwwt4
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