You have entities with bidirectional relationships. How do you ensure these are correctly managed in Spring JPA to avoid common issues like infinite recursion?

Bidirectional relationships in JPA, where two entities each hold a reference to the other, need to be configured carefully with an owning side and a mappedBy side, and handled deliberately during JSON serialization to avoid infinite recursion between the two entities calling each other's getters endlessly.

Key Points: • One side owns the relationship and controls the foreign key; the other side uses mappedBy to point back to the owning field, avoiding duplicate join columns or tables. • Both sides of the in-memory relationship must be kept in sync manually, typically with a helper method that updates both collections/references together. • @JsonManagedReference (on the owning/forward side) and @JsonBackReference (on the back-reference side) tell Jackson to serialize one direction and skip the other, preventing infinite recursion. • A cleaner, more scalable alternative to reference annotations is to use dedicated DTOs for API responses instead of serializing entities directly, giving full control over what's exposed. • Lazy loading (the default for collections) also needs care here, since accessing the back-reference outside a transaction can trigger a LazyInitializationException.

Example: An Order entity has a List<OrderItem> and each OrderItem has a back-reference to its Order; without @JsonManagedReference/@JsonBackReference (or a DTO), serializing an Order to JSON would serialize its items, each of which would try to serialize its parent Order again, recursing forever.

Code Example:

@Entity
public class Order {
    @Id @GeneratedValue
    private Long id;

    @OneToMany(mappedBy = "order", cascade = CascadeType.ALL)
    @JsonManagedReference
    private List<OrderItem> items = new ArrayList<>();
}

@Entity
public class OrderItem {
    @Id @GeneratedValue
    private Long id;

    @ManyToOne
    @JoinColumn(name = "order_id")
    @JsonBackReference
    private Order order;
}

Interview Tip: A concise interview answer is:

"I set up the relationship with a clear owning side that holds the foreign key and a mappedBy side on the other entity, and I keep both sides in sync in code with a helper method. For serialization, I either use @JsonManagedReference and @JsonBackReference to break the recursive cycle, or, more often in real projects, I just expose DTOs from the API instead of serializing entities directly, which sidesteps the whole problem."