Testcontainers + MockMvc Most developers test their database code against an in-memory database. It's fast, it's easy to set up, and it lies to you. Your production app runs on PostgreSQL. Your tests run on H2, which has a different engine, different behavior, and different edge cases. You can have 100% passing tests and still ship a bug that only exists in production. So I made a different choice. My integration tests spin up a real PostgreSQL container via Testcontainers, run every assertion, then tear it down. My end-to-end tests go one step further using MockMvc to fire real HTTP requests through the full Spring stack, hitting the actual controller, service, repository, and database. No shortcuts at any layer. No mocks. No surprises in production. Testcontainers (testcontainers.com) makes this easy; it supports Java, Go, Python, .NET, and has native integration with Spring Boot 3+. Not the easiest path. The correct one. --- 💬 Do you test against a real database or an in-memory one? Drop it in the comments. 🔗 Full project: https://lnkd.in/dse3hHTV 🔗 Testcontainers: https://testcontainers.com #Java #SpringBoot #Testing #BackendDevelopment #SoftwareEngineering
Testing with Real PostgreSQL via Testcontainers and MockMvc
More Relevant Posts
-
🚀 Week 1 Progress Report Focused on building strong fundamentals across multiple areas: 💡 DSA: Arrays, Recursion, started Dynamic Programming 💻 Full Stack: Started React, Spring Boot CRUD APIs completed ☕ Java: Strengthening core concepts ⚙️ System Design: Basics + URL Shortener project 🧠 Aptitude: Clock & Calendar, Time & Work 🗄️ DBMS: SQL (DDL, DML), CRUD operations, Joins 📈 Consistency > intensity. Building step by step. #DSA #FullStack #Java #SpringBoot #React #SQL #SystemDesign #LearningJourney
To view or add a comment, sign in
-
#Post4 In the previous post, we understood how request mapping works using @GetMapping and others. Now the next question is 👇 How does Spring Boot handle data sent from the client? That’s where @RequestBody comes in 🔥 When a client sends JSON data → it needs to be converted into a Java object. Example request (JSON): { "name": "User", "age": 25 } Controller: @PostMapping("/user") public User addUser(@RequestBody User user) { return user; } 👉 Spring automatically converts JSON → Java object This is done using a library called Jackson (internally) 💡 Why is this useful? • No manual parsing needed • Clean and readable code Key takeaway: @RequestBody makes it easy to handle request data in APIs 🚀 In the next post, we will understand @PathVariable and @RequestParam 🔥 #Java #SpringBoot #BackendDevelopment #RESTAPI #LearnInPublic
To view or add a comment, sign in
-
We've been building something quietly for a while, and I'm ready to share it. OpenTaint is an open-source taint analysis engine with the most thorough Spring Boot support. https://lnkd.in/darQ5ZRN Not "Java support." Actual modeling of how Spring works. Spring Boot's annotation-driven architecture creates data flows that are invisible to conventional static analysis. A bean injection crosses class boundaries with no call site in the source. JPA persistence links two HTTP endpoints through the database with no shared code path. A Freemarker configuration object determines whether user input reaching template.process() is exploitable — or harmless. These are not edge cases. This is the default architecture of most Java web applications. OpenTaint traces tainted data through every layer: - Following data across file and class boundaries — through DTO field access and method chains. - Resolving configuration-aware sinks — tracing through DI to determine whether a resolver or handler is actually exploitable. - Connecting endpoints through persistence — where the database or service state is the only link. - Distinguishing dangerous fields from safe ones — at per-column granularity within those flows. The engine operates on bytecode, resolves virtual dispatch, and maps every finding back to its HTTP endpoint. If you're using Semgrep or CodeQL on your Java/Kotlin/Spring codebase — try OpenTaint on the same project and compare what it finds. We've published reproducible comparisons on the blog, but seeing it on your own code is more convincing. Apache 2.0 + MIT. Engine, rules, CLI, GitHub Action, GitLab CI — everything is open source. #java #kotlin #spring #springboot #security #appsec #opensource #sast #taintanalysis
To view or add a comment, sign in
-
-
The @Transactional Proxy Pitfall Think slapping @Transactional on a method guarantees database rollback on failure? Think again. 🚨 One of the most common critical bugs I see in Spring Boot applications isn't a logic error—it's a misunderstanding of how Spring AOP (Aspect-Oriented Programming) works under the hood. Enter the Self-Invocation Problem. If you have a non-transactional method processOrder() that calls a @Transactional method saveToDatabase() within the exact same class, that transaction will never start. If an exception is thrown, your data will not roll back. 💥 Why does this happen? Spring manages transactions using proxies. When an external class calls your bean, it hits the proxy first, which starts the transaction. But when you make an internal method call (calling this.saveToDatabase()), you are bypassing the proxy entirely and calling the raw object. No proxy = no transaction. How to fix it: 1️⃣ Refactor: Move the @Transactional method to a separate dedicated Service class (Best Practice). 2️⃣ Self-Injection: Inject the class into itself using @Autowired or constructor injection, and call the method via the injected instance. 3️⃣ AspectJ: Switch from proxy-based AOP to AspectJ weaving (Heavyweight, but solves proxy limitations). Understanding the framework's internal mechanics is the difference between writing code that compiles and writing systems that are truly fault-tolerant. Have you ever been bitten by the Spring proxy self-invocation trap? What is your favorite obscure Spring Boot "gotcha"? Let's geek out in the comments! 👇 Tags: #Java #SpringBoot #SoftwareEngineering #BackendDevelopment #AdvancedJava #SystemDesign #CodingTips
To view or add a comment, sign in
-
-
⚠️ Hot Reload in Spring Boot Isn’t Magic. It’s ClassLoader Isolation. When you change code and see: 👉 App restarts in seconds 👉 No full JVM restart What’s really happening? 1️⃣ Two ClassLoaders — The Core Idea Spring Boot DevTools splits your app into: Base ClassLoader → dependencies (stable) Restart ClassLoader → your application code (changing) 2️⃣ Why This Matters Dependencies (like Spring, Hibernate): Loaded once Heavy to reload Rarely change Your code: Changes frequently Needs fast reload So only your code is reloaded. 3️⃣ What Happens on Code Change You modify a .class file DevTools detects change (file watcher) Discards Restart ClassLoader Creates a new one Reloads your classes Base ClassLoader stays untouched 4️⃣ Why It’s Faster Than Full Restart Without DevTools: JVM restarts All classes reloaded Framework reinitialized With DevTools: Only your classes reload Dependencies reused Startup drastically reduced 5️⃣ What Actually Gets Restarted? Spring ApplicationContext Beans created again Config reloaded But: 👉 JVM process stays alive 👉 Core libraries remain loaded 6️⃣ Common Gotcha (Very Important) Static state survives in Base ClassLoader. Example: static Map cache = new HashMap(); If loaded by base loader: It won’t reset after reload Leads to weird bugs 7️⃣ Why Some Changes Don’t Reload DevTools won’t reload when: Dependency JAR changes Config outside classpath changes Native resources updated Requires full restart 8️⃣ Comparison With Other Tools Tool Approach DevTools ClassLoader restart JRebel Bytecode rewriting HotSwap Limited JVM replacement DevTools doesn’t “reload classes” It replaces the ClassLoader that loaded them #Java #SpringBoot #JVM #ClassLoader #HotReload #BackendEngineering #SoftwareEngineering #LearnInPublic
To view or add a comment, sign in
-
𝗔𝗳𝘁𝗲𝗿 𝗿𝗲𝘃𝗶𝗲𝘄𝗶𝗻𝗴 𝗵𝘂𝗻𝗱𝗿𝗲𝗱𝘀 𝗼𝗳 𝗣𝗥𝘀, 𝗜 𝗸𝗲𝗲𝗽 𝘀𝗲𝗲𝗶𝗻𝗴 𝘁𝗵𝗲 𝘀𝗮𝗺𝗲 𝗽𝗲𝗿𝗳𝗼𝗿𝗺𝗮𝗻𝗰𝗲 𝗶𝘀𝘀𝘂𝗲. The developer did everything right: clean code, proper repository, correct relationships. And yet, the application was making 𝟱𝟬 𝗱𝗮𝘁𝗮𝗯𝗮𝘀𝗲 𝗾𝘂𝗲𝗿𝗶𝗲𝘀 to display a single page. Nobody noticed. Until production. This is the N+1 problem. In simple terms: instead of 1 query, your app makes 1 + N, one for each item. You don't see it in your code. You see it in your logs: 1 query for orders, then 1 query per customer. 500 orders = 501 queries. The reflex fix? Switch to EAGER loading. That's often the wrong answer. The real fix is understanding 𝘄𝗵𝗮𝘁 𝘆𝗼𝘂'𝗿𝗲 𝗹𝗼𝗮𝗱𝗶𝗻𝗴 𝗮𝗻𝗱 𝘄𝗵𝗲𝗻. Need the data always? use JOIN FETCH Need it sometimes? use @EntityGraph Need full control? use DTO query N+1 is not a JPA bug. It's a judgment problem: the difference between code that works locally and systems that perform in production. I've attached a visual breakdown of these 3 approaches with real examples. Have you ever shipped something that worked perfectly in dev… but broke in production? #Java #SpringBoot #JPA #Hibernate #Backend #Performance #SoftwareEngineering
To view or add a comment, sign in
-
Most used Spring Boot annotations (that you’ll see almost everywhere) If you’ve worked with Spring, you already know… half the magic is in annotations 😅 Here are some of the ones I keep using almost daily: * @SpringBootApplication → starting point of the app * @RestController → tells Spring this class handles APIs * @RequestMapping / @GetMapping / @PostMapping → for routing requests * @Autowired → dependency injection (used a lot, sometimes too much 👀) * @Service → business logic layer * @Repository → database layer * @Component → generic bean * @Entity → maps class to DB table * @Id → primary key * @Configuration → for config classes * @Bean → manually define beans when needed When I started, I used to just memorize these. Over time, I realised understanding when NOT to use them is equally important. Like: * overusing @Autowired everywhere * mixing @Component, @Service randomly * not understanding bean lifecycle Spring feels simple at start, but there’s a lot going under the hood. If you’re learning Spring right now → focus less on remembering, more on understanding what each annotation actually does. Which Spring annotation do you use the most? 👇 #ThoughtForTheDay #SpringBoot #Java #Backend #SoftwareEngineering
To view or add a comment, sign in
-
-
Understanding #SpringBoot Flow Architecture If you are diving into backend development with Java, understanding how data flows through a Spring Boot application is a game-changer. I found this great visual that simplifies the entire process. Here is a quick breakdown of how a request actually travels through the system: 1. The #Client (The Start) Everything begins with the Client (like a web browser or a mobile app) sending an HTTPS Request. This could be anything from logging in to fetching a list of products. 2. The #Controller (The Gatekeeper) The request first hits the Controller. Think of this as the front desk. It handles the incoming request, decides where it needs to go, and sends back the final response to the user. 3. The #Service Layer (The Brain) The Controller passes the job to the Service Layer. This is where the "magic" happens—all the business logic, calculations, and rules are kept here. Pro Tip: This layer uses Dependency Injection to pull in the Repository it needs to talk to the database. 4. The #Repository & Model (The Data Handlers) Repository: This class extends CRUD services, allowing the app to Create, Read, Update, or Delete data without writing complex SQL every time. Model: This represents the structure of your data (like a "User" or "Product" object). 5. #Database (The Memory) Finally, using JPA / Spring Data, the application communicates with the Database to store or retrieve the information requested by the client. #SpringBoot #Java #Spring #SpringSecurity #SystemDesign #Backend
To view or add a comment, sign in
-
-
Day 21. My API crashed with a StackOverflowError. Not because of bad code. Because of a relationship I didn’t think twice about. I had this: @Entity public class User { @OneToMany(mappedBy = "user") private List<Order> orders; } @Entity public class Order { @ManyToOne private User user; } Looks normal. Until you return it as JSON. Here’s what actually happens: → User → Orders → User → Orders → User… → Infinite recursion → StackOverflowError → Your API crashes That’s not a bug. That’s how your model is designed. Hibernate understands it. Jackson doesn’t. So I fixed it. (see implementation below 👇) Now: → DTOs control the response → No circular references → No accidental data explosion The hard truth: → Bidirectional relationships are easy to write → They’re dangerous to expose → You won’t notice until production Returning entities is convenient. Controlling your API response is what makes you a backend developer. Have you ever hit this error? 👇 Drop it below #SpringBoot #Java #Hibernate #BackendDevelopment #JavaDeveloper
To view or add a comment, sign in
-
-
Most Spring Boot apps I've reviewed in production don't fail because of bad logic. They fail because of 𝗹𝗮𝘇𝘆 𝗱𝗲𝗳𝗮𝘂𝗹𝘁 𝗰𝗼𝗻𝗳𝗶𝗴𝘂𝗿𝗮𝘁𝗶𝗼𝗻𝘀 that nobody questioned. Here's what I wish someone told me earlier. Stop returning entity objects directly from your controllers. It seems convenient until you accidentally expose sensitive fields or break your API contract when the schema changes. Always map to a dedicated response DTO. Your future self will thank you when a database column rename doesn't trigger a client-side outage. Use constructor injection instead of `@Autowired` on fields. It makes your dependencies explicit, simplifies testing, and lets the compiler catch missing beans before runtime does. Spring actually recommends this approach. Java @RestController public class OrderController { private final OrderService orderService; public OrderController(OrderService orderService) { this.orderService = orderService; } } Configure 𝘀𝗲𝗽𝗮𝗿𝗮𝘁𝗲 𝗽𝗿𝗼𝗳𝗶𝗹𝗲𝘀 for each environment from day one. Hardcoding values in `application.properties` and "fixing it later" is technical debt that compounds fast. Use `application-dev.yml`, `application-prod.yml`, and externalize secrets through environment variables or a vault. One more thing people overlook: 𝗮𝗹𝘄𝗮𝘆𝘀 𝘀𝗲𝘁 𝗲𝘅𝗽𝗹𝗶𝗰𝗶𝘁 𝘁𝗿𝗮𝗻𝘀𝗮𝗰𝘁𝗶𝗼𝗻 𝗯𝗼𝘂𝗻𝗱𝗮𝗿𝗶𝗲𝘀 with `@Transactional` on your service layer, not your repository layer. It gives you control over rollback behavior when multiple repositories are involved. What's one Spring Boot default you learned the hard way should have been overridden? #SpringBoot #Java #BackendDevelopment #SoftwareEngineering #CleanCode
To view or add a comment, sign in
Explore related topics
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
Excellent!!