๐Ÿ”ด The Error You're Seeing

Confirm this matches your console output. If it does, you're in the right place.

ERROR LOG2026-02-14 09:30:45.200 ERROR 8842 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: org.springframework.http.converter.HttpMessageConversionException: Type definition error: [simple type, class com.devinhyderabad.entity.User]; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Infinite recursion (StackOverflowError)] with root cause java.lang.StackOverflowError: null

โšก Quick Fix Works 80% of the time

Add @JsonIgnore to the 'child' side of the relationship to stop Jackson from serializing it.

@ManyToOne @JoinColumn(name = "department_id") @JsonIgnore private Department department;

๐Ÿ› ๏ธ Solutions (3 Ways to Fix)

Solution 1โœ“ Most common cause

Use @JsonIgnore on the inverse side

๐Ÿ‘‰ Use this for a quick fix when you don't need the related data in the JSON response.

If User has a List of Orders, and Order has a User field, add @JsonIgnore to the User field in the Order class. Jackson will stop traversing there.

@Entity public class Order { @ManyToOne @JsonIgnore // Stops infinite loop private User user; }
Solution 2

Use @JsonManagedReference and @JsonBackReference

๐Ÿ‘‰ Use this if you want to keep the data in the JSON but break the cycle cleanly.

Annotate the 'parent' side (the List) with @JsonManagedReference, and the 'child' side (the object reference) with @JsonBackReference. Jackson handles the cycle perfectly.

@Entity public class User { @OneToMany(mappedBy = "user") @JsonManagedReference private List<Order> orders; } @Entity public class Order { @ManyToOne @JsonBackReference private User user; }
Solution 3

Return DTOs instead of Entities

๐Ÿ‘‰ Use this as the enterprise best practice.

Never return JPA Entities directly from @RestController. Map them to DTOs inside your service layer. This completely avoids JSON recursion and lazy loading exceptions.

@GetMapping public List<UserDTO> getUsers() { return userService.getAllUsers().stream() .map(u -> new UserDTO(u.getName(), u.getOrders().size())) .collect(Collectors.toList()); }

๐Ÿ“‹ Version Notes

Spring Boot 2.x

Uses Jackson 2.x. Standard recursion handling.

Spring Boot 3.x

Uses Jackson 2.15+. Stricter memory limits cause StackOverflow to trigger faster.

๐Ÿง  Why this Happens

Tap to expand the deep technical explanation

Your JPA entities have a bidirectional relationship (e.g., User has a List of Orders, and Order has a reference back to User). When Spring tries to convert the User to JSON, Jackson goes to User -> Orders -> User -> Orders indefinitely until the JVM runs out of stack memory.

The HITEC City Parking Spot Analogy:

Imagine two mirrors facing each other. You look into one mirror and see an infinite tunnel of mirrors reflecting each other. Jackson tries to serialize that infinite tunnel and crashes.

๐Ÿ›ก๏ธ How to Prevent This Next Time

Always separate your database entities from your API responses using Data Transfer Objects (DTOs).

Course Search
Search across all chapters & stages
๐Ÿ“–

Search the course

Type any topic โ€” branching, stash, rebase, hooks โ€” and jump straight to that chapter.

merge branchesgit stashundo commitrebase