Spring Boot REST API and Spring Data JPA Interview Questions
15 questions on REST controllers, validation, exception handling, JPA entities, repositories, transactions, and the N+1 problem.
1. What is the difference between @Controller and @RestController?
@Controller returns view names for server-rendered pages. @RestController is @Controller plus @ResponseBody, so every method's return value is written straight to the HTTP response, usually as JSON. Use @RestController for APIs.
2. How do you map request data to method parameters?
@PathVariable reads from the URL path, @RequestParam from the query string or form, @RequestBody deserializes the JSON body, @RequestHeader reads a header, and @ModelAttribute binds form fields to an object.
@RestController @RequestMapping("/api/orders") class OrderController { @GetMapping("/{id}") Order get(@PathVariable Long id) { return service.find(id); } @PostMapping ResponseEntity<Order> create(@Valid @RequestBody CreateOrder request) { Order saved = service.create(request); return ResponseEntity.status(HttpStatus.CREATED).body(saved); } }3. How do you validate request data?
Add the spring-boot-starter-validation dependency, put Jakarta Bean Validation annotations (@NotBlank, @Size, @Email, @Min) on the request class, and add @Valid to the parameter. Failures throw MethodArgumentNotValidException, which you convert into a clear 400 response in an exception handler.
4. How do you handle exceptions globally?
Create a class annotated with @RestControllerAdvice and write @ExceptionHandler methods that map exceptions to responses. Spring 6 and Boot 3 support the RFC 7807 problem detail format through ProblemDetail, giving clients a consistent error body.
@RestControllerAdvice class ApiErrors { @ExceptionHandler(NotFoundException.class) ProblemDetail notFound(NotFoundException ex) { return ProblemDetail.forStatusAndDetail(HttpStatus.NOT_FOUND, ex.getMessage()); } }5. Which HTTP status codes should a REST API return?
200 OK for a successful read or update, 201 Created (with a Location header) for a new resource, 204 No Content for success with no body, 400 for invalid input, 401 when not authenticated, 403 when authenticated but not allowed, 404 when not found, 409 for conflicts, and 500 for unexpected server errors. Use them consistently.
6. Why should you return DTOs instead of JPA entities from controllers?
Entities expose your database structure, can leak sensitive fields, are tied to lazy-loading behavior (causing serialization errors or extra queries), and make it hard to evolve the API independently of the schema. DTOs (records work well) define exactly what the API accepts and returns.
7. What is Spring Data JPA, and what does a repository give you?
Spring Data JPA builds on JPA and Hibernate. You declare an interface extending JpaRepository, and Spring generates the implementation with CRUD, paging, and sorting methods. You can add derived query methods by naming them, or write queries with @Query.
interface UserRepository extends JpaRepository<User, Long> { Optional<User> findByEmail(String email); List<User> findByActiveTrueOrderByNameAsc(); @Query("select u from User u where u.createdAt > :since") List<User> recent(@Param("since") Instant since); }8. What are the main JPA annotations for an entity?
@Entity marks the class, @Table sets the table name, @Id marks the primary key, @GeneratedValue configures key generation, @Column adjusts column details, and relationships use @OneToOne, @OneToMany, @ManyToOne, and @ManyToMany with @JoinColumn. An entity needs a no-argument constructor (which can be protected) and should implement equals and hashCode carefully.
9. What is the difference between lazy and eager fetching?
Lazy loading fetches related data only when it is accessed, and eager loading fetches it together with the parent. Collections default to lazy, and @ManyToOne and @OneToOne default to eager. Prefer lazy relationships and fetch what a use case needs explicitly with a join fetch or an entity graph.
10. What is the N+1 select problem, and how do you fix it?
Loading N parents and then triggering one extra query per parent to fetch a lazy relationship results in N+1 queries. Fix it by fetching the data together: a JOIN FETCH query, @EntityGraph on the repository method, or batch fetching with hibernate.default_batch_fetch_size. Turn on SQL logging in development to spot it.
@Query("select o from Order o join fetch o.items where o.customerId = :id") List<Order> findWithItems(@Param("id") Long id);11. How does @Transactional work?
Spring wraps the bean in a proxy that begins a transaction before the method runs and commits when it finishes, or rolls back on a RuntimeException or Error (checked exceptions do not roll back by default; set rollbackFor if needed). Because it uses proxies, calling a @Transactional method from another method of the same class bypasses the proxy and no transaction starts, and private methods are not intercepted.
12. What are transaction propagation and isolation?
Propagation controls how a transactional method behaves when a transaction already exists: REQUIRED (the default) joins it, REQUIRES_NEW suspends it and starts a new one, and others such as SUPPORTS or NEVER cover special cases. Isolation sets the visibility level between concurrent transactions (READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE) and defaults to the database's default.
13. How do you paginate and sort results?
Pass a Pageable to a repository method and receive a Page, which includes content and total counts. Use Slice when you do not need the total, or keyset pagination for very large tables.
Page<Product> page = repository.findAll(PageRequest.of(0, 20, Sort.by("name")));14. What do ddl-auto and database migrations do?
spring.jpa.hibernate.ddl-auto can create or update tables from entities, which is convenient for local development but dangerous in production. Use a migration tool such as Flyway or Liquibase, which runs versioned SQL scripts on startup so schema changes are repeatable, reviewed, and tracked.
15. How do you call another service from Spring Boot?
Use RestClient (Spring 6.1 and newer) for synchronous calls, WebClient for reactive or non-blocking calls, or declarative HTTP interfaces. The older RestTemplate still works but is in maintenance mode. Always set timeouts, handle errors, and consider retries and a circuit breaker for resilience.
Interview Tips
- Know the proxy limitation of @Transactional; it is a favorite follow-up question.
- Show that you separate API models (DTOs) from persistence models (entities).
- Enable SQL logging when you describe performance tuning, and mention N+1 explicitly.