Jackson লাইব্রেরি যখন bidirectional relationships (যেমন: একাধিক ক্লাস একে অপরকে রেফার করছে) প্রসেস করে, তখন infinite recursion বা circular references সমস্যা সৃষ্টি হতে পারে। এটি সাধারণত তখন ঘটে যখন একটি অবজেক্ট A অন্য একটি অবজেক্ট B কে রেফার করে এবং অবজেক্ট B আবার অবজেক্ট A কে রেফার করে। এই ধরনের relationships-এর ক্ষেত্রে JSON Serialization বা Deserialization-এর সময় একে অপরকে অবিরত রেফারেন্স করা হলে StackOverflowError সৃষ্টি হয়।
Jackson এর @JsonManagedReference এবং @JsonBackReference অ্যানোটেশন ব্যবহার করে এই সমস্যা সমাধান করা যায়।
Bidirectional Relationships এবং Infinite Recursion Problem
Bidirectional Relationship Example:
ধরা যাক, আমাদের দুটি ক্লাস User এবং Order আছে যেখানে User ক্লাস Order ক্লাসকে রেফার করে এবং Order ক্লাস User ক্লাসকে রেফার করে।
public class User {
private int id;
private String name;
private List<Order> orders; // User has many Orders
// Constructors, Getters, and Setters
}
public class Order {
private int id;
private String product;
private User user; // Order is associated with a User
// Constructors, Getters, and Setters
}
এখানে, User ক্লাস এবং Order ক্লাস একে অপরকে রেফার করছে, যা একে অপরকে bidirectionally রেফারেন্স করছে। যখন Jackson এই ক্লাসগুলোর JSON তৈরির চেষ্টা করবে, তখন এটি infinite recursion তৈরি করবে, কারণ User থেকে Order এবং Order থেকে আবার User রেফারেন্স করবে। এর ফলে StackOverflowError হতে পারে।
Jackson-এ Infinite Recursion Problem সমাধান
Jackson-এ এই Bidirectional Relationships সমস্যা সমাধান করতে দুটি গুরুত্বপূর্ণ অ্যানোটেশন ব্যবহার করা হয়:
@JsonManagedReference- মূল অবজেক্ট (parent) থেকে রেফার করা অবজেক্টের (child) ফিল্ডে এই অ্যানোটেশন ব্যবহার করা হয়।@JsonBackReference- child অবজেক্ট থেকে parent অবজেক্টে রেফার করা ফিল্ডে এই অ্যানোটেশন ব্যবহার করা হয়।
@JsonManagedReference এবং @JsonBackReference এর ব্যবহার
@JsonManagedReference এবং @JsonBackReference একসাথে ব্যবহার করলে, parent অবজেক্ট (এখানে User) child অবজেক্টের (এখানে Order) সার্ভিসিং করতে সক্ষম হয়, কিন্তু child অবজেক্ট (এখানে Order) আবার parent অবজেক্টকে রেফার করলে @JsonBackReference ওই রেফারেন্সটি JSON এ Serialize হতে দেবে না, ফলে infinite recursion প্রতিরোধ হবে।
কোড উদাহরণ:
User ক্লাস:
import com.fasterxml.jackson.annotation.JsonManagedReference;
import java.util.List;
public class User {
private int id;
private String name;
@JsonManagedReference
private List<Order> orders; // Parent side
// Constructors, Getters, and Setters
}
Order ক্লাস:
import com.fasterxml.jackson.annotation.JsonBackReference;
public class Order {
private int id;
private String product;
@JsonBackReference
private User user; // Child side
// Constructors, Getters, and Setters
}
Serialization Example
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Arrays;
public class JsonManagedReferenceExample {
public static void main(String[] args) throws Exception {
User user = new User();
user.setId(1);
user.setName("Rahim");
Order order1 = new Order();
order1.setId(101);
order1.setProduct("Laptop");
Order order2 = new Order();
order2.setId(102);
order2.setProduct("Phone");
user.setOrders(Arrays.asList(order1, order2));
order1.setUser(user);
order2.setUser(user);
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(user);
System.out.println(json);
}
}
JSON Output:
{
"id": 1,
"name": "Rahim",
"orders": [
{
"id": 101,
"product": "Laptop"
},
{
"id": 102,
"product": "Phone"
}
]
}
এখানে, Order অবজেক্টের মধ্যে User অবজেক্টের রেফারেন্স বাদ দেওয়া হয়েছে, কারণ @JsonBackReference অ্যানোটেশন ব্যবহার করা হয়েছে।
Additional Jackson Features for Circular References:
1. @JsonIdentityInfo
@JsonIdentityInfo ব্যবহার করে Circular Reference সমস্যা আরও সহজে সমাধান করা যায়। এটি একটি Object ID তৈরি করে, যা circular references ট্যাগ করতে সাহায্য করে।
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public class User {
private int id;
private String name;
private List<Order> orders; // Parent side
// Constructors, Getters, and Setters
}
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public class Order {
private int id;
private String product;
private User user; // Child side
// Constructors, Getters, and Setters
}
Serialization Output with @JsonIdentityInfo:
{
"id": 1,
"name": "Rahim",
"orders": [
{
"id": 101,
"product": "Laptop",
"user": 1
},
{
"id": 102,
"product": "Phone",
"user": 1
}
]
}
এখানে, @JsonIdentityInfo ব্যবহার করে প্রতিটি অবজেক্টের ID অনুযায়ী circular references মোকাবেলা করা হয়েছে, এবং একই অবজেক্টের জন্য রেফারেন্স করা ID ব্যবহার করা হয়েছে।
Summary of Key Annotations for Circular References
| Annotation | বর্ণনা |
|---|---|
@JsonManagedReference | Parent অবজেক্টে ব্যবহৃত হয়, যা child এর serialization এ সাহায্য করে। |
@JsonBackReference | Child অবজেক্টে ব্যবহৃত হয়, যা parent এর recursive references আটকায়। |
@JsonIdentityInfo | Object ID দিয়ে circular references মোকাবেলা করে। |
- Bidirectional relationships JSON Serialization/Deserialization-এ infinite recursion সমস্যা সৃষ্টি করতে পারে।
@JsonManagedReferenceএবং@JsonBackReferenceব্যবহার করে সহজেই circular references সমাধান করা সম্ভব।@JsonIdentityInfoব্যবহার করে object ID-based circular references সমাধান করা যায়।- Jackson-এর এই অ্যানোটেশনগুলো JSON ডেটা ফরম্যাট এবং performance নিয়ন্ত্রণে সহায়তা করে, বিশেষত complex relationships এর ক্ষেত্রে।
Read more