Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
A direct command skips the review prompt. Inspect the source before running it.
["API endpoint requirements or domain model specifications","Performance or configuration issues with Spring Boot apps","JPA entity relationship design questions","Security configuration needs"]
outputs
["Spring Boot REST controllers with proper patterns","JPA entity mappings and repository queries","Security configuration with Spring Security","Production-ready application.yml configuration"]
linksTo
["postgresql","redis","docker","kubernetes"]
linkedFrom
[]
riskLevel
low
memoryReadPolicy
selective
memoryWritePolicy
none
sideEffects
[]
Spring Boot Patterns & Best Practices
Purpose
Provide expert guidance on Spring Boot application architecture, auto-configuration, REST API development, JPA/Hibernate patterns, and production-grade configuration. Covers Spring Boot 3.x with Jakarta EE, virtual threads, and GraalVM native image support.
publicinterfaceOrderRepositoryextendsJpaRepository<Order, UUID> {
// Derived query
List<Order> findByUserIdAndStatus(UUID userId, OrderStatus status);
// JPQL with fetch join to avoid N+1@Query("SELECT o FROM Order o JOIN FETCH o.items WHERE o.id = :id")
Optional<Order> findByIdWithItems(@Param("id") UUID id);
// Native query for complex reporting@Query(value = """
SELECT DATE_TRUNC('month', o.created_at) AS month,
COUNT(*) AS order_count,
SUM(oi.price * oi.quantity) AS revenue
FROM orders o
JOIN order_items oi ON oi.order_id = o.id
WHERE o.status = 'COMPLETED'
GROUP BY month
ORDER BY month DESC
""", nativeQuery = true)
List<MonthlyRevenueProjection> getMonthlyRevenue();
// Specification for dynamic filtering
Page<Order> findAll(Specification<Order> spec, Pageable pageable);
}
spring:application:name:my-servicedatasource:url:jdbc:postgresql://${DB_HOST:localhost}:${DB_PORT:5432}/${DB_NAME:mydb}username:${DB_USER:postgres}password:${DB_PASS:postgres}hikari:maximum-pool-size:${DB_POOL_SIZE:10}minimum-idle:2connection-timeout:5000jpa:open-in-view:false# Always disable — prevents lazy loading in controllershibernate:ddl-auto:validate# Use Flyway/Liquibase for migrationsproperties:hibernate:default_batch_fetch_size:16order_inserts:trueorder_updates:truejdbc.batch_size:50threads:virtual:enabled:true# Spring Boot 3.2+ virtual threadsmanagement:endpoints:web:exposure:include:health,info,metrics,prometheusendpoint:health:show-details:when-authorizedserver:shutdown:gracefullifecycle:timeout-per-shutdown-phase:30s
Always disable open-in-view — Prevents lazy-loading queries from firing inside controllers, which causes performance issues and breaks transactional boundaries.
Use DTOs, not entities, in controllers — Never expose JPA entities directly. Use records for request/response DTOs and MapStruct for mapping.
Prefer constructor injection — Use @RequiredArgsConstructor (Lombok) over @Autowired field injection for testability.
Use @Transactional(readOnly = true) at class level — Override with @Transactional only on write methods. This enables read-replica routing and Hibernate flush-mode optimization.
Fetch joins for N+1 prevention — Use JOIN FETCH in JPQL or @EntityGraph annotations to eagerly load associations when needed.
Use Flyway or Liquibase for migrations — Never rely on ddl-auto in production. Set it to validate.
Enable virtual threads (Spring Boot 3.2+) — For I/O-bound workloads, virtual threads eliminate the need for reactive programming in most cases.
Use ProblemDetail for errors — Spring 6 supports RFC 9457 Problem Details natively.
Configure Hikari pool carefully — maximum-pool-size should be (2 * CPU cores) + disk_spindles for most workloads.
Enable batch inserts/updates — Configure hibernate.jdbc.batch_size and order_inserts/updates for bulk operations.
Common Pitfalls
Pitfall
Problem
Fix
open-in-view: true (default)
Lazy loading in controller causes extra queries
Set spring.jpa.open-in-view: false
N+1 queries
Loading collections triggers per-entity queries
Use JOIN FETCH or @EntityGraph
Exposing entities in API
Tight coupling, circular refs, security leaks
Use DTO records + MapStruct
ddl-auto: update in prod
Schema drift, data loss risk
Use validate + Flyway migrations
Missing @Version
Lost updates under concurrency
Add optimistic locking with @Version
Blocking calls with WebFlux
Mixing blocking JPA with reactive stack
Use virtual threads instead of WebFlux for JPA apps