← ClaudeAtlas

mir-backend-jvm-springlisted

Make It Right (Spring Boot module). Spring Boot + Spring Data JPA/Hibernate + Spring Security + Spring MVC/WebFlux reliability footguns specific to this framework stack. Covers: @Transactional self-invocation (same-bean call bypasses the proxy → no transaction), checked exceptions not rolling back by default, propagation/isolation pitfalls, JPA/Hibernate N+1 with lazy associations, LazyInitializationException outside the session, OPEN_IN_VIEW antipattern, singleton bean scope storing per-request state, @Async needing an explicit thread pool and swallowing exceptions, @Valid + DTOs against overposting, and Spring Security method-level authorization for object-level checks. Always loads TOGETHER WITH mir-backend (the gates) and mir-backend-jvm (JVM runtime concerns: thread pools, virtual threads, GC, container heap, cold start, JMM visibility, ThreadLocal hygiene); this module only adds Spring Boot / Spring Data library mechanics. TRIGGER only when the JVM backend stack is Spring Boot — building, reviewing, or
anantbhandarkar/make-it-right · ★ 12 · API & Backend · score 83
Install: claude install-skill anantbhandarkar/make-it-right
# /mir-backend-jvm-spring · Make It Right (Spring Boot) Bottom tier of the chain: `mir-backend` (generic gates) → `mir-backend-jvm` (JVM runtime model) → **this** (Spring Boot / Spring Data library mechanics). Run the gates first; load the JVM runtime tier for threading, GC, and container-heap concerns; reach for *this* at Gate 5 (design mechanics), Gate 6 (implementation), and Gate 7 review. **Runtime-level concerns (virtual-thread pinning, pool sizing, GC tuning, `-XX:MaxRAMPercentage`, ThreadLocal hygiene) live in `mir-backend-jvm` — not here.** **Stack assumed:** Spring Boot 3.x · Spring Data JPA (Hibernate 6) · Spring MVC or WebFlux · Spring Security · PostgreSQL / MySQL. Notes call out WebFlux divergences explicitly. ## The Spring Boot footguns AI walks into most ### 1. @Transactional self-invocation: the proxy bypass Spring's `@Transactional` is implemented via a proxy (AOP). When a bean method calls *another method on the same bean instance* (`this.someMethod()`), the call goes **directly to the target object, not through the proxy** — the transaction advice is never applied. ```java @Service public class OrderService { // WRONG — calling settle() from within the same class bypasses the proxy; // settle() does NOT run in a transaction even though it is annotated. public void process(Order order) { settle(order); // direct call on 'this' — proxy not involved } @Transactional public void settle(Order order) { ... } }