In Spring Boot, @JsonIgnore and @JsonBackReference are Jackson Library annotations that control JSON serialization and prevent infinite recurrences in bidirectional relationships. This guide explains the difference Between @JsonIgnore and @JsonBackReference, use cases, and when to use each in Spring Boot applications.
What is @JsonIgnore?
It is used to exclude a specific property of the Java Bean from JSON serialization and deserialization. It is a simple way to prevent a field from appearing in API responses or being set via requests.
Key Features of @JsonIgnore
- Removes field from JSON responses and requests.
- Prevents sensitive data exposure (e.g., passwords).
- Applies to any field, method, or class.
Example: Using @JsonIgnore
import com.fasterxml.jackson.annotation.JsonIgnore;
public class User {
private String username;
@JsonIgnore
private String password; // Will not be included in JSON responses
// Getters and Setters
}
JSON Output
{
"username": "peter"
}
Explanation
- The password field is ignored in JSON responses and cannot be set in JSON requests.
What is @JsonBackReference?
@JsonBackReference is used to handle bidirectional relationships in JSON serialization. It prevents infinite recursion by designating the “child” side of the relationship as a back-reference that is not serialized.
Key Features of @JsonBackReference
- Solves infinite recursion issues in bidirectional relationships.
- Works with @JsonManagedReference on the parent side.
- Prevents serialization of the back-reference while allowing deserialization.
@JsonBackReference and @JsonManagedReference example
import com.fasterxml.jackson.annotation.JsonBackReference;
import com.fasterxml.jackson.annotation.JsonManagedReference;
import javax.persistence.*;
import java.util.List;
@Entity
public class Department {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@OneToMany(mappedBy = "department")
@JsonManagedReference // Forward reference (Parent side)
private List<Employee> employees;
// Getters and Setters
}
@Entity
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@ManyToOne
@JsonBackReference // Backward reference (Child side)
private Department department;
// Getters and Setters
}
JSON Output for Department Object
{
"id": 1,
"name": "HR",
"employees": [
{
"id": 101,
"name": "Alice"
},
{
"id": 102,
"name": "Bob"
}
]
}
Explanation
- The Department entity serializes its employee list.
- The Employee entity does not serialize the department field due to @JsonBackReference, preventing recursion.
Key Difference Between @JsonIgnore and @JsonBackReference
Feature | @JsonIgnore | @JsonBackReference |
Purpose | Excludes a field from JSON serialization. | Handles bidirectional relationships in JSON. |
Use Case | Hides sensitive or unnecessary fields. | Prevents infinite recursion in bidirectional mappings. |
Works With | Any field in a class. | Works with @JsonManagedReference in parent-child relationships. |
Effect on Serialization | The field is completely removed from JSON output. | Prevents serialization of the back-reference. |
Effect on Deserialization | The field is ignored in the input JSON. | Allows deserialization (data can be set via JSON request). |
Best For | Sensitive fields like passwords, and tokens. | Handling bidirectional entity relationships. |
When to Use @JsonIgnore
- Sensitive Data Protection: Hide fields like passwords or tokens from API responses.
- Reduce API Payload Size: Exclude unnecessary fields that are not needed in JSON.
- Prevent Modification: Ensure some fields cannot be updated via JSON requests.
Example Use Case
@JsonIgnore
private String creditCardNumber;
When to Use @JsonBackReference
- Fix Infinite Recursion: Prevent stack overflow issues when serializing bidirectional relationships.
- Maintain Data Integrity: Ensure that the parent object retains child references but not vice versa.
- Enable Proper Deserialization: Allows setting the child reference while preventing unwanted JSON cycles.
Example Use Case
@JsonBackReference
private Department department;
Using Both Together
In some cases, you may need to use both annotations for different purposes.
Example: Combined Usage
@Entity
public class Employee {
@Id
private Long id;
private String name;
@JsonIgnore // Completely ignored in JSON
private String ssn;
@ManyToOne
@JsonBackReference // Prevents infinite recursion
private Department department;
// Getters and Setters
}
- @JsonIgnore hides ssn from JSON output.
- @JsonBackReference ensures the department reference is not serialized, preventing infinite recursion.
Practical Comparison
Scenario | @JsonIgnore | @JsonBackReference |
Hide sensitive data from API responses | ✅ Yes | ❌ No |
Prevent infinite recursion | ❌ No | ✅ Yes |
Exclude a field from serialization | ✅ Yes | ✅ Yes (for back-references only) |
Exclude a field from deserialization | ✅ Yes | ❌ No (still allows deserialization) |
Works with bidirectional relationships | ❌ No | ✅ Yes |
Best Practices
- If we want to hide a field, @JsonIgnore is the simplest approach.
- When dealing with bidirectional mappings, prefer @JsonBackReference with @JsonManagedReference.
- Always verify that JSON serialization behaves as expected, especially with complex entity mappings.
- If a field needs to be hidden for security and also has bidirectional mapping, use both annotations strategically.
Conclusion
The @JsonIgnore and @JsonBackReference annotations in Spring Boot serve different purposes:
- @JsonIgnore is used to exclude fields from JSON completely (both serialization and deserialization).
- @JsonBackReference is used to prevent infinite recursion in bidirectional relationships while allowing proper deserialization.
By understanding their differences and use cases, we can effectively manage JSON serialization in our Spring Boot applications.