Skip to main content

Spring Boot Code Review Checklist

Rapid-scan checklist for Spring Boot code reviews. Use this to quickly identify issues, then dive into linked documentation for details.


Security Red Flags - Block PR Immediately

  • SQL injection risk: String concatenation in SQL queries instead of parameterized queries → SQL Injection Prevention
  • Sensitive data in logs: Credit cards, passwords, API keys, SSNs, PII in log statements → Sensitive Data Protection
  • Hardcoded secrets: Passwords, API keys, tokens embedded in source code → Configuration Management
  • Missing input validation: User input not validated with Bean Validation annotations → Input Validation
  • Path traversal vulnerability: User input directly in file paths without validation/sanitization → Path Traversal Prevention
  • Stack traces exposed: Error responses include stack traces or internal implementation details → Error Handling Security
  • Entities exposed in API: JPA entities returned directly from REST controllers → REST Controllers
  • Money as double/float: Financial amounts using floating-point types instead of BigDecimal → Entity Design
  • Mass assignment vulnerability: Accepting entities directly in request body instead of DTOs → Mass Assignment Prevention
  • XSS vulnerability: User input rendered without encoding or sanitization → XSS Prevention

Common Mistakes

Dependency Injection

  • Field injection (@Autowired on fields) instead of constructor injection → Dependency Injection
  • Missing final modifier on injected dependencies
  • Using @Autowired annotation when constructor injection works automatically
  • Circular dependencies between services (design smell)

Transaction Management

  • Missing @Transactional annotation on service methods that modify data → Service-Layer Transactions
  • @Transactional on repository methods instead of service layer
  • Missing readOnly = true on read-only service methods → Service-Layer Transactions
  • Wrong transaction propagation settings for use case → Transaction Propagation
  • @Transactional on private methods (doesn't work due to proxy limitations)
  • Transactions spanning multiple use cases (transaction boundaries too broad)

Configuration

  • Using scattered @Value annotations instead of @ConfigurationPropertiesConfiguration Management
  • Missing validation annotations on configuration properties
  • Hardcoding environment-specific values instead of using profiles
  • Sensitive configuration not externalized to environment variables

REST API Design

  • Missing @Valid annotation on request bodies → Request Validation
  • Incorrect HTTP status codes (e.g., returning 200 for POST instead of 201) → HTTP Methods and Semantics
  • Missing @Validated on controller class (needed for path variable validation)
  • No global exception handler for validation errors → Global Exception Handling
  • Using @Controller instead of @RestController for REST APIs
  • Inconsistent error response format (not following RFC 7807) → Global Exception Handler

Data Access & JPA

  • Using H2 for integration tests instead of TestContainers with real PostgreSQL → Why PostgreSQL Over H2
  • Missing indexes on frequently queried columns or foreign keys
  • open-in-view: true enabled (default) instead of disabled → Configuration
  • Entity attribute names don't match database column names (missing @Column(name="..."))
  • Lazy-loaded collections accessed outside transaction boundary
  • Missing @NoArgsConstructor(access = AccessLevel.PROTECTED) on JPA entities

Watch For - Performance & Correctness Issues

N+1 Query Problems

Pagination

  • List endpoints without pagination support → Pagination
  • Missing @PageableDefault annotation with sensible defaults
  • Unbounded findAll() queries that could return thousands of records
  • Custom pagination implementation instead of using Spring Data Pageable

Exception Handling

  • Catching generic Exception instead of specific exception types
  • Swallowing exceptions without logging or rethrowing
  • Exception messages exposing sensitive information or implementation details
  • Using exceptions for control flow instead of validation
  • Not handling OptimisticLockingFailureException from versioned entities → Optimistic Locking

Entity Design Issues

  • Missing @Version field for optimistic locking on entities with concurrent updates → Optimistic Locking
  • Using EnumType.ORDINAL instead of EnumType.STRINGEntity Best Practices
  • Missing @PrePersist / @PreUpdate callbacks for timestamp management
  • Bidirectional relationships without proper management methods
  • Missing orphanRemoval = true when child entities should be deleted with parent

Logging Issues

  • Using string concatenation in log statements instead of placeholders → Logging
  • Wrong log levels (DEBUG for production errors, ERROR for informational messages)
  • Not logging correlation IDs for request tracing
  • Logging entire request/response objects (may contain sensitive data)
  • Missing context in log messages (customer ID, transaction ID, etc.)

Modern Java & Spring Boot Features


Best Practices - Code Quality

General Spring Boot

REST APIs

Data Access

Security

Testing

  • Unit tests with mocked dependencies for service layer logic → Spring Boot Testing
  • Integration tests with TestContainers for repository layer → Spring Boot Testing
  • Test coverage for happy path, error cases, and edge cases
  • Mutation testing configured and passing threshold
  • Contract tests for API endpoints consuming external services

Quick Scan Table

CategoryWhat to CheckSeverityReference
SecurityParameterized queries (no string concat in SQL)BlockSQL Injection
SecurityNo sensitive data in logsBlockSensitive Data
SecurityNo hardcoded secretsBlockConfiguration
SecurityInput validation with Bean ValidationBlockInput Validation
SecurityDTOs used (not entities in API)BlockREST Controllers
SecurityGeneric error messagesBlockError Handling
Transactions@Transactional on service write methodsFixTransactions
TransactionsreadOnly = true on read methodsFixTransactions
PerformanceJOIN FETCH or @EntityGraph (avoid N+1)FixN+1 Queries
PerformancePagination on list endpointsFixPagination
API@Valid on request bodiesFixValidation
GOOD:APICorrect HTTP status codesReview
GOOD:DIConstructor injection (not field)Review
GOOD:Config@ConfigurationProperties (not @Value)Review
Entities@Version for optimistic lockingFixOptimistic Locking
EntitiesEnumType.STRING (not ORDINAL)FixEntities
EntitiesBigDecimal for money (not double)BlockEntity Design

Legend:

  • Block PR - Security vulnerability or data corruption risk
  • Fix Before Merge - Performance issue, correctness problem, or likely bug
  • [GOOD] Review & Discuss - Code quality improvement

Additional Considerations

Code Smells Beyond the Basics

  • Services with too many dependencies (>5 injected fields indicates poor cohesion)
  • Methods longer than 30-40 lines (consider extracting)
  • Classes larger than 300-400 lines (consider splitting by feature)
  • Duplicate validation logic across multiple services
  • Business logic leaking into controllers or repositories
  • Inconsistent naming conventions across the codebase
  • Missing JavaDoc for public APIs and complex methods
  • TODOs or FIXMEs without tracking tickets

Database-Specific Issues

  • Missing database indexes on columns used in WHERE clauses
  • Queries without LIMIT clause that could return unbounded results
  • Using native SQL when JPQL would work (reduces portability)
  • Cartesian joins (missing join conditions)
  • Missing database constraints that duplicate application validation
  • Migrations that can't be rolled back
  • Schema changes without corresponding application code changes

Observability & Operations

  • Missing correlation IDs in MDC for distributed tracing → Spring Boot Observability
  • No metrics exposed for business-critical operations
  • Missing health check indicators for external dependencies
  • No structured logging (JSON format for log aggregation)
  • Missing alerts configuration for critical errors
  • No retry/circuit breaker for external service calls → Spring Boot Resilience

API Design Beyond Basics

  • Missing API versioning strategy → API Versioning
  • No rate limiting on public endpoints → Rate Limiting
  • Missing CORS configuration for web clients → CORS Configuration
  • Inconsistent naming conventions for endpoints
  • Missing cache headers for cacheable responses
  • No content negotiation for multiple formats

Block Checklist - Must Fix Before Merge

Use this final checklist before approving:

  • No SQL injection vulnerabilities (all queries parameterized)
  • No sensitive data in logs (passwords, cards, SSNs, API keys masked/omitted)
  • No hardcoded secrets (credentials from environment)
  • Input validation present on all user input
  • No path traversal vulnerabilities
  • Entities not exposed in REST APIs (DTOs used)
  • No stack traces in API error responses
  • BigDecimal used for all monetary amounts
  • Write operations have @Transactional
  • No unbounded queries (pagination on list endpoints)

Core Spring Boot Guides:

Cross-Cutting Topics: