Complete AI prompt library for Spring Boot developers. Covers REST APIs with Spring WebFlux, Spring Security JWT, Spring Data JPA with Hibernate, Testcontainers integration testing, Kafka event streaming, Docker deployment, and performance tuning.
Spring Boot in 2026: Java's Enterprise-Grade API Framework
Spring Boot 3.x with Java 21 is a fundamentally different platform from the Spring Boot 2.x that dominates most AI training data. Virtual threads, records, sealed classes, Spring Security's new lambda DSL, and native compilation with GraalVM require modern prompts that explicitly target the new APIs. These prompts produce code that compiles and runs correctly on Spring Boot 3.x — not legacy configurations that require migration.
Picking the Right AI Model for Spring Boot Work
Spring Boot 3's Jakarta EE migration is the single biggest trap for AI models — anything trained primarily on pre-2023 Java code still generates javax.* imports. That's the first check for any AI-generated Spring Boot code.
| Model | Best For (Spring Boot) | Weak Spot | When to Reach For It |
|---|---|---|---|
| Claude Sonnet | Spring Security lambda DSL, JPA relationships, Spring Boot 3 architecture | Occasionally still generates legacy XML config for very specific Spring modules | Designing the security filter chain, reviewing JPA entity mappings, planning the service/repository layering |
| ChatGPT GPT-5.5 | REST controller scaffolding, entity and DTO generation | Generates javax.* imports (Spring Boot 2) instead of jakarta.* (Spring Boot 3) | Generating controller boilerplate from an OpenAPI spec, writing DTO classes from entity descriptions |
| Gemini 3.5 Flash | Java ecosystem research, Spring vs Quarkus vs Micronaut comparisons, GraalVM native | Less depth on Spring Security specifics | Researching the Spring Boot 3 upgrade path, comparing Hibernate 6 vs older ORM versions |
| Cursor | In-editor completion aware of your entity and repository pattern | Sometimes generates constructor injection incorrectly in complex bean graphs | Writing service methods when it can see your repository interfaces and entity classes |
| GitHub Copilot | Boilerplate: DTOs, mappers, CRUD repositories | Spring Boot 2 patterns (WebSecurityConfigurerAdapter instead of SecurityFilterChain bean) | Generating MapStruct mapper implementations, writing JUnit 5 test stubs |
| Grok | Direct comparison: Spring Boot vs Quarkus vs Micronaut for startup time and memory | Less depth on Spring Data JPA specifics | Getting a direct benchmark-based answer on whether native compilation is worth the GraalVM tradeoffs |
| DeepSeek | Boilerplate generation, Lombok annotation usage, test data setup | Spring Security configuration is often incorrect or outdated | Generating @Builder Lombok patterns, writing Testcontainers setup boilerplate |
The Jakarta namespace migration from Spring Boot 2.x to 3.x is non-negotiable: every import javax.persistence.* must be import jakarta.persistence.*, every javax.validation must be jakarta.validation. Always include "Spring Boot 3.x with Jakarta EE 10 imports" in your system context. Any model generating javax.* is generating code that won't compile in Spring Boot 3.
1. Spring Boot 3 Project Setup
You are a senior Spring Boot 3 architect using Java 21.
Design a production Spring Boot 3.3 application for a multi-tenant SaaS REST API:
- Build: Gradle (Kotlin DSL), not Maven
- Java 21 with virtual threads enabled (spring.threads.virtual.enabled=true)
- Spring Web MVC (not WebFlux — virtual threads provide the throughput we need)
- Spring Data JPA + Hibernate 6 + PostgreSQL
- Spring Security 6 with JWT (stateless)
- Spring Cache + Redis (Lettuce client)
- Spring Actuator for health and metrics
- Kafka for domain events
Deliver:
1. build.gradle.kts with all dependencies and versions
2. Package structure: com.company.app.{domain}/{application,domain,infrastructure,presentation}
3. application.yml for local development, application-prod.yml for production (env var placeholders)
4. Docker Compose for local: PostgreSQL 16, Redis 7, Kafka 3.7
5. The top 3 Spring Boot 3 features you are using and why they matter
2. REST Controller with Validation
You are a Spring Boot 3 REST API expert.
Build a complete TaskController for a project management API:
Endpoints: GET /api/v1/tasks (paginated), GET /api/v1/tasks/{id}, POST /api/v1/tasks, PUT /api/v1/tasks/{id}, DELETE /api/v1/tasks/{id}
Requirements:
- @RestController with @RequestMapping("/api/v1/tasks")
- @Validated on controller class for constraint validation
- DTOs: TaskCreateRequest (record with @Valid constraints), TaskUpdateRequest (record, all fields Optional), TaskResponse (record, mapped from entity)
- Tenant scoping: extract organizationId from JWT (SecurityContextHolder), pass to service
- Response wrapper: ApiResponse<T> record { T data, String requestId, Instant timestamp }
- Error handling: @RestControllerAdvice with handlers for MethodArgumentNotValidException (field errors), EntityNotFoundException (404), AccessDeniedException (403)
- Pagination: return Page<TaskResponse> wrapped in ApiResponse
Use Java 21 records for all DTOs. No Lombok required — use records and canonical constructors.
3. Spring Security JWT Configuration
You are a Spring Security 6 expert.
Configure JWT authentication for a Spring Boot 3 REST API using the SecurityFilterChain approach (NOT WebSecurityConfigurerAdapter):
Security config:
- Stateless session: SessionCreationPolicy.STATELESS
- CORS: allowedOrigins from environment, allowedMethods GET/POST/PUT/DELETE/OPTIONS
- CSRF: disabled (stateless JWT API)
- Public endpoints: /api/v1/auth/**, /actuator/health, /swagger-ui/**
- All other endpoints: authenticated
JWT filter (JwtAuthenticationFilter extends OncePerRequestFilter):
- Extract Bearer token from Authorization header
- Validate with JJWT (io.jsonwebtoken:jjwt-impl)
- Extract claims: userId, organizationId, role
- Set UsernamePasswordAuthenticationToken in SecurityContext
Token service:
- Generate access token (RS256, 15 minutes) — keys loaded from environment as Base64
- Generate refresh token (opaque UUID stored in Redis, 7 days TTL)
- Validate token: check signature, expiry, and not-blacklisted
- Refresh: validate Redis entry, issue new pair, invalidate old refresh token
Method security:
- @EnableMethodSecurity on config class
- Use @PreAuthorize("hasRole('ORG_ADMIN')") on admin endpoints
- Custom permission evaluator: @PreAuthorize("@taskPermissionEvaluator.canEdit(#taskId, authentication)")
Output: SecurityConfig, JwtAuthenticationFilter, JwtTokenService, and PermissionEvaluator.
4. Spring Data JPA Repository with Optimization
You are a Spring Data JPA and Hibernate 6 expert.
Design JPA entities and repositories for a multi-tenant task management system:
Entities (Java 21 — use @Entity with records where possible, standard classes where JPA requires):
- Organization, User, Project, Task, AuditLog
- Auditing: @EnableJpaAuditing, @CreatedDate, @LastModifiedDate, @CreatedBy, @LastModifiedBy
- Soft delete: @SQLRestriction("deleted_at IS NULL") on entities (Hibernate 6 syntax — not @Where)
- Multi-tenant: @Filter for organizationId (Hibernate Filter, activated per request in interceptor)
TaskRepository (JpaRepository + custom):
- findByProjectIdAndStatus(projectId, status, Pageable): @EntityGraph to load assignee
- findOverdueTasks(organizationId, now): @Query JPQL with date comparison
- bulkUpdateStatus(taskIds, status): @Modifying @Query @Transactional — single UPDATE statement
- countByStatusGrouped(organizationId): @Query returning List<StatusCount> projection interface
- findWithFilters(spec, pageable): JpaSpecificationExecutor for dynamic filtering
Performance:
- @QueryHints with COMMENT for DBA query identification
- @BatchSize on collections to prevent N+1 with IN clause batching
- Database indexes: composite indexes declared in @Table(indexes={...})
Output: entity classes, repositories, Hibernate filter configuration, and tenant activation interceptor.
5. Kafka Event Streaming
You are a Spring Kafka expert.
Implement domain event streaming for a Spring Boot application:
Domain events (records):
- TaskCreatedEvent(taskId, title, projectId, organizationId, createdBy, occurredAt)
- TaskStatusChangedEvent(taskId, previousStatus, newStatus, changedBy, occurredAt)
- TaskAssignedEvent(taskId, previousAssignee, newAssignee, occurredAt)
Producer:
- KafkaTemplate<String, Object> with JSON serializer
- Topic naming: app.tasks.events (single topic, event type in header)
- Transactional outbox pattern: save event to outbox table in same DB transaction as entity save
- Outbox relay: @Scheduled task polls outbox table, publishes to Kafka, marks as published
Consumer (notification-service):
- @KafkaListener on tasks.events topic, partitioned by organizationId key
- Idempotency: check event ID in Redis before processing (TTL 24h)
- Error handling: DefaultErrorHandler with exponential backoff (1s, 2s, 4s), dead-letter topic after 3 failures
- Manual acknowledgment: only commit offset after successful processing
Topics configuration: 12 partitions, replication-factor 3 (production), 1 (local Docker)
Output: KafkaConfig, event records, TaskEventPublisher, outbox table + scheduler, TaskEventConsumer.
6. Testcontainers Integration Tests
You are a Spring Boot testing expert using Testcontainers.
Write integration tests for TaskController using real PostgreSQL and Redis:
Test setup:
- @SpringBootTest(webEnvironment = RANDOM_PORT)
- @Testcontainers at class level
- @Container static PostgreSQLContainer (shared across all tests in class for speed)
- @Container static GenericContainer for Redis
- @DynamicPropertySource: inject container URLs into Spring DataSource and Redis config
- TestRestTemplate or WebTestClient for HTTP calls
Test data:
- @Sql(scripts = {"/sql/clean.sql", "/sql/seed-tasks.sql"}) per test method
- Helper: createAuthToken(userId, organizationId, role) — real JWT signed with test key
Tests:
1. GET /api/v1/tasks: 200, correct pagination, only current org's tasks returned
2. POST /api/v1/tasks: 201, task in DB, Kafka event published (EmbeddedKafka)
3. POST with invalid data: 400, field-level error map in response
4. GET /api/v1/tasks/{id}: 404 for different org's task (tenant isolation)
5. DELETE: 204, soft-deleted (deletedAt set), excluded from subsequent GET
6. Concurrent update: two threads update same task → optimistic lock exception → 409
Show: Testcontainers setup class (reusable across test classes), JWT helper, and SQL seed file.
8. Spring Boot with Kafka Event Streaming
You are a senior Spring Boot 3 microservices engineer.
Add Apache Kafka event streaming to a Spring Boot 3 + Java 21 application:
Dependencies: spring-kafka, spring-boot-starter-json
Producer:
- KafkaTemplate<String, Object> with JSON serialization
- TaskEventProducer: publish TaskCreatedEvent, TaskUpdatedEvent, TaskCompletedEvent to 'task-events' topic
- Key: tenantId (ensures messages for same tenant land on same partition)
- Transactional producer: @Transactional wraps DB write + Kafka publish — both succeed or both fail
Consumer:
- @KafkaListener(topics = "task-events", groupId = "notification-service")
- Manual acknowledgment (AckMode.MANUAL): ack.acknowledge() only after successful processing
- Error handling: SeekToCurrentErrorHandler with DeadLetterPublishingRecoverer — failed messages go to 'task-events.DLT'
- Idempotency: store event ID in Redis (SETNX) — skip if already processed
Topic configuration: 3 partitions, replication factor 3 (production), retention 7 days
Health check: custom HealthIndicator that checks Kafka broker connectivity
Output: Kafka producer, consumer, event classes (Java 21 records), configuration, and Docker Compose snippet for local Kafka.
9. Spring Data JPA: Complex Queries and Specifications
You are a Spring Data JPA expert.
Write advanced JPA queries for a task management system:
1. JPQL with JOIN FETCH (avoid N+1): fetch Tasks with their assignees and projects in a single query, filtered by organizationId and status
2. Specification pattern (JpaSpecificationExecutor):
- TaskSpecification: buildSpec(TaskFilterDTO filter) — compose predicates for status, priority, assigneeId, dueDateRange, tenantId (always required)
- Combine with Pageable for paginated, filterable results
3. Native query with pagination: tasks overdue by priority for a dashboard widget — needs a custom COUNT query for pagination
@Query(value = "...", countQuery = "...", nativeQuery = true)
4. Projection interface: TaskSummaryProjection — only id, title, status, assigneeName (computed from firstName + lastName) — avoids loading full entity graph for list views
5. @EntityGraph: define for Task entity to specify which associations to eagerly load — different graphs for detail view (all) vs list view (none)
Requirements:
- All queries must include tenantId predicate — fail the build if a query doesn't
- Use Jakarta Persistence (not javax) imports throughout
- Hibernate 6.4 syntax
Output: repository interface, Specification class, and the 5 query implementations with brief explanation of why each approach was chosen.
End-to-End Workflow: New Microservice Feature
Shipping a new notification service endpoint in a Spring Boot 3 microservice:
- Domain model (Prompt 2 variant): "Create Notification JPA entity with Jakarta Persistence annotations: id (UUID), recipientId (UUID), type (enum: TASK_ASSIGNED, TASK_DUE, MENTION), channel (EMAIL, IN_APP, PUSH), payload (JSON column with Hibernate Type), isRead, readAt, createdAt. Include Audit fields via @EntityListeners(AuditingEntityListener.class)."
- Repository + Service: "Create NotificationRepository extends JpaRepository with Specification support. Create NotificationService with: createNotification(), markAsRead(id, userId), markAllRead(userId), getUnreadCount(userId). All methods enforce tenantId scoping."
- REST controller (Prompt 3 variant): "Create NotificationController with endpoints: GET /notifications (paginated), PATCH /notifications/{id}/read, PATCH /notifications/read-all, GET /notifications/unread-count. JWT auth via Spring Security, swagger annotations."
- Tests (Prompt 5 variant): "Write @SpringBootTest integration tests for NotificationController using Testcontainers (PostgreSQL). Test pagination, read status update, cross-tenant access (assert 403), and unread count accuracy."
Where AI Goes Wrong in Spring Boot
- javax.* imports instead of jakarta.*. The most common and immediately breaking failure. Spring Boot 3 requires Jakarta EE 10 — any javax.persistence, javax.validation, or javax.servlet import won't compile. Specify "Spring Boot 3.x, Jakarta EE 10 imports only" in every prompt.
- Deprecated WebSecurityConfigurerAdapter. AI still generates Spring Security config by extending WebSecurityConfigurerAdapter — removed in Spring Security 6. The correct pattern is a SecurityFilterChain @Bean. Always verify the security config pattern.
- Missing @Transactional on service methods. AI-generated service methods often omit @Transactional. Without it, multi-step operations that fail partway through leave the database in an inconsistent state. Check every service method that writes to multiple tables.
- N+1 queries in JPA relationships. AI generates @ManyToOne without @ManyToOne(fetch = FetchType.LAZY), causing eager loading everywhere. Also generates @OneToMany without JOIN FETCH, causing N+1 queries in loops. Both destroy performance at scale.
- Hardcoded database credentials in test config. AI generates application-test.properties with hardcoded H2 or PostgreSQL credentials. Use Testcontainers for integration tests — it's the Spring Boot 3 standard and avoids environment-specific test failures.
7. Good vs Bad Spring Boot Prompts
| Task | ❌ Bad Prompt | ✅ Good Prompt |
|---|---|---|
| Security | "Add JWT auth to Spring Boot" | "Configure Spring Security 6 JWT for Spring Boot 3 using SecurityFilterChain (not WebSecurityConfigurerAdapter): stateless session, JwtAuthenticationFilter extends OncePerRequestFilter, RS256 validation with JJWT, userId + organizationId + role in claims, @PreAuthorize on methods." |
| JPA | "Query tasks from the database" | "Write a Spring Data JPA @Query for tasks filtered by organizationId, status, and due_date range with Pageable. Use @EntityGraph to load assignee (prevent N+1). Add @Modifying @Transactional for the bulk status update method. Use Hibernate 6 @SQLRestriction for soft delete filtering." |
| Testing | "Write tests for my API" | "Write Testcontainers integration tests for TaskController: real PostgreSQL 16 + Redis 7 containers, @Sql seed data per test, real JWT token factory, assert HTTP status + response body + DB state + Kafka event published. Test tenant isolation: org A cannot access org B's tasks." |
Before You Prompt: Spring Boot Context Setup
Spring Boot 3's Jakarta EE migration is the single biggest source of AI-generated compilation errors. Any model trained before mid-2023 produces javax.* imports that don't compile on Spring Boot 3. This block eliminates that and the other top Spring Boot 3 pitfalls:
Context for all Spring Boot prompts in this session:
- Framework: Spring Boot 3.4 + Java 21
- CRITICAL: All imports must use jakarta.* (NOT javax.*)
Spring Boot 3 uses Jakarta EE 10 — javax.persistence, javax.validation do NOT exist
- Security: SecurityFilterChain with lambda DSL
NEVER generate: WebSecurityConfigurerAdapter (removed in Spring Boot 3)
- JPA: Spring Data JPA + Hibernate 6.x, PostgreSQL
- Virtual threads: spring.threads.virtual.enabled=true (use for blocking I/O)
- Testing: Testcontainers with real PostgreSQL (NEVER H2 in-memory)
H2 has SQL dialect differences that hide production bugs
- Build: Maven or Gradle with spring-boot-starter-* dependencies only
Put "jakarta.* ONLY, never javax.*" in every Spring Boot prompt, even outside this context block. This is the #1 compile-time error from AI-generated Spring Boot code and it's invisible unless you run mvn compile. The Testcontainers requirement prevents a more subtle problem: H2's different SQL dialect lets queries pass tests that would fail on PostgreSQL's strict type system.
3 Common Mistakes When Prompting AI for Spring Boot
Mistake 1: javax.* imports instead of jakarta.*
Spring Boot 3 migrated from Java EE to Jakarta EE 10 — every javax.persistence, javax.validation, and javax.servlet import is now jakarta.persistence, jakarta.validation, jakarta.servlet. AI models trained on Spring Boot 2 code generate the old namespace. The error is a clean compilation failure (package javax.persistence does not exist), so it's caught early — but it wastes time. Write "jakarta.* imports only, Spring Boot 3" in every entity and security-related prompt.
Mistake 2: WebSecurityConfigurerAdapter in Spring Security
WebSecurityConfigurerAdapter was deprecated in Spring Boot 2.7 and removed in Spring Boot 3.0. AI still generates it because it appears in millions of tutorials. The modern approach is a @Configuration class that exposes a SecurityFilterChain bean using the lambda DSL. Specify: "Spring Security with SecurityFilterChain bean and lambda DSL — never WebSecurityConfigurerAdapter, it does not exist in Spring Boot 3." Include this in every authentication prompt.
Mistake 3: H2 in-memory database for integration tests
H2 supports a PostgreSQL compatibility mode but doesn't enforce many of PostgreSQL's constraints: strict type casting, window functions, full-text search syntax, and JSONB operations all behave differently. Tests passing against H2 can fail against real PostgreSQL in production. Specify: "use Testcontainers with a real postgresql:16 container — never H2." Testcontainers starts a real PostgreSQL Docker container for tests, giving you exact production behavior at the cost of a few extra seconds of test startup.
Further Reading
Resources for AI-assisted Spring Boot and Java development:
- How engineering teams use AI to accelerate Java development — AI strategies for Spring Boot teams: architecture reviews, automated test generation, and API design
- How to write the perfect AI prompt — the principles behind every prompt in this guide, applicable to any Java framework
- AI Coding Prompt Library — 50+ copy-ready prompts for Spring Boot, JPA, Spring Security, Kafka, and Java testing
Generate a custom Spring Boot prompt → Try PromptPrepare free
Help & Answers
Frequently Asked Questions
Found this helpful?
Save it to your library or share with your team.
Keep Reading