@JsonManagedReference এবং @JsonBackReference Jackson এর দুটি অ্যানোটেশন যা Circular References সমস্যার সমাধান করতে ব্যবহৃত হয়। যখন দুটি বা তার বেশি অবজেক্ট একে অপরকে রেফারেন্স করে, তখন এটি Circular Reference তৈরি করতে পারে, যা JSON Serialization/Deserialization-এর সময় StackOverflowError সৃষ্টি করতে পারে। এই সমস্যা এড়াতে Jackson এই দুটি অ্যানোটেশন প্রদান করে।
@JsonManagedReference: একটি ফরওয়ার্ড রেফারেন্সকে চিহ্নিত করে এবং এটি ডেটার Serialization প্রক্রিয়ার সময় main object-এর অংশ হিসেবে প্রসেস হয়।@JsonBackReference: একটি ব্যাক রেফারেন্সকে চিহ্নিত করে এবং এটি ডেটার Serialization প্রক্রিয়ায় কার্যকর হয় না, বরং শুধুমাত্র সেই ক্ষেত্রটিকে উপেক্ষা করে।
Circular Reference এবং এর সমস্যা
ধরা যাক, আমাদের কাছে Parent এবং Child ক্লাস রয়েছে, যেখানে Parent ক্লাস Child ক্লাসের একটি ইনস্ট্যান্স ধারণ করে এবং Child ক্লাস আবার Parent ক্লাসের রেফারেন্স ধারণ করে। এটি Circular Reference তৈরি করে।
public class Parent {
private String name;
private Child child;
// Getters and Setters
}
public class Child {
private String name;
private Parent parent;
// Getters and Setters
}
যখন আপনি Parent অবজেক্ট JSON-এ Serialize করতে যান, তখন Child অবজেক্টের রেফারেন্সের জন্য এটি আবার Parent অবজেক্টের রেফারেন্স প্রদান করবে এবং এটি infinite recursion এর সৃষ্টি করবে।
@JsonManagedReference এবং @JsonBackReference এর সমাধান
1. @JsonManagedReference এবং @JsonBackReference ব্যাখ্যা
@JsonManagedReference: এটি সাধারণত parent অবজেক্টের ফিল্ডে ব্যবহার করা হয় এবং এটি child অবজেক্টের JSON ফিল্ডকেই ম্যানেজ করে।@JsonBackReference: এটি child অবজেক্টের ফিল্ডে ব্যবহৃত হয় এবং এটি@JsonManagedReferenceদ্বারা ব্যবস্থাপিত অংশের রেফারেন্স ফিল্ডে যুক্ত হয়, কিন্তু এটি serialization থেকে বাদ পড়ে।
ব্যবহার উদাহরণ:
import com.fasterxml.jackson.annotation.JsonManagedReference;
import com.fasterxml.jackson.annotation.JsonBackReference;
public class Parent {
private String name;
@JsonManagedReference
private Child child;
// Constructor, Getters and Setters
}
public class Child {
private String name;
@JsonBackReference
private Parent parent;
// Constructor, Getters and Setters
}
Serialization Example:
import com.fasterxml.jackson.databind.ObjectMapper;
public class JsonManagedBackReferenceExample {
public static void main(String[] args) throws Exception {
Parent parent = new Parent();
parent.setName("Rahim");
Child child = new Child();
child.setName("Ali");
parent.setChild(child);
child.setParent(parent);
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(parent);
System.out.println(json);
}
}
JSON Output:
{
"name": "Rahim",
"child": {
"name": "Ali"
}
}
Explanation:
@JsonManagedReferenceকেবলParentঅবজেক্টের অংশ হিসাবেChildঅবজেক্টের ফিল্ডকে JSON আউটপুটে অন্তর্ভুক্ত করবে।@JsonBackReferenceদ্বারাChildঅবজেক্টেরparentফিল্ডকে JSON থেকে বাদ দেওয়া হবে, ফলে Circular Reference এড়ানো যাবে।
@JsonManagedReference এবং @JsonBackReference এর উপকারিতা
- Circular Reference সমস্যা সমাধান:
- যখন দুটি অবজেক্ট একে অপরকে রেফার করে, তখন এই অ্যানোটেশনগুলি ব্যবহার করে আপনি Circular Reference সমস্যা এড়াতে পারেন।
- Complex Object Relationships Handling:
- Parent-Child বা অন্যান্য জটিল অবজেক্ট রিলেশনশিপ গুলোর মধ্যে ফিল্ড-এ হ্যান্ডলিং সহজ হয়।
- Efficient Serialization:
@JsonManagedReferenceএবং@JsonBackReferenceব্যবহার করে JSON ফরম্যাটে ডেটা কীভাবে সিরিয়ালাইজ হবে, সেটি সঠিকভাবে নিয়ন্ত্রণ করা যায় এবং unnecessary data serialization থেকে রক্ষা পাওয়া যায়।
@JsonManagedReference এবং @JsonBackReference এর তুলনা
| Feature | @JsonManagedReference | @JsonBackReference |
|---|---|---|
| Usage | Parent বা forward reference-এর জন্য ব্যবহৃত হয়। | Child বা backward reference-এর জন্য ব্যবহৃত হয়। |
| Serialization | Serialization-এর সময় field টি অন্তর্ভুক্ত হয়। | Serialization-এর সময় field টি উপেক্ষা করা হয়। |
| Relation | Parent-Child relation এ parent side এর জন্য। | Parent-Child relation এ child side এর জন্য। |
| Purpose | Circular reference হ্যান্ডলিং করে। | Circular reference এড়াতে ব্যবহার হয়। |
@JsonManagedReferenceএবং@JsonBackReferenceCircular Reference সমাধান করতে ব্যবহৃত হয়, যখন দুটি অবজেক্ট একে অপরকে রেফার করে।@JsonManagedReferenceparent object এবং@JsonBackReferencechild object এর মধ্যে ব্যবহৃত হয়।- এই অ্যানোটেশনগুলো infinite recursion থেকে বাঁচাতে এবং JSON output কে সঠিকভাবে কাস্টমাইজ করতে সহায়ক।
এভাবে Circular References সমস্যা সমাধান করা যায় এবং JSON Serialization-এর জন্য সঠিক কাঠামো তৈরি করা সম্ভব।
@JsonManagedReference এবং @JsonBackReference হল Jackson-এর দুইটি অ্যানোটেশন, যা Circular References (যখন একটি অবজেক্ট অন্য অবজেক্টকে রেফার করে এবং তার মধ্যে পুনরায় রেফারেন্স তৈরি হয়) নিয়ন্ত্রণ করতে ব্যবহৃত হয়। এটি বিশেষত Parent-Child রিলেশনশিপের ক্ষেত্রে উপকারী, যেখানে দুটি অবজেক্ট একে অপরকে রেফার করে।
@JsonManagedReference এবং @JsonBackReference এর কাজ
- Circular Reference Handling:
- Jackson-এ Circular References থাকলে, এটি JSON Serialization করার সময় অসীম লুপ তৈরি করতে পারে, যার ফলে
StackOverflowErrorহতে পারে। @JsonManagedReferenceএবং@JsonBackReferenceএই Circular Reference সমস্যা সমাধান করে, যেখানে একটি ফিল্ডকে "managed" (ব্যবস্থাপিত) হিসেবে চিহ্নিত করা হয় এবং অন্যটি "back" (পিছন থেকে) চিহ্নিত হয়।
- Jackson-এ Circular References থাকলে, এটি JSON Serialization করার সময় অসীম লুপ তৈরি করতে পারে, যার ফলে
- One-way Serialization:
@JsonManagedReferenceঅ্যানোটেশনটি Parent অবজেক্টে ব্যবহার করা হয়, এবং@JsonBackReferenceঅ্যানোটেশনটি Child অবজেক্টে ব্যবহার করা হয়। এইভাবে, Child অবজেক্টের রেফারেন্স Parent অবজেক্টে সিঙ্গল দিকের (one-way) Serialization-এ পরিণত হয়।
@JsonManagedReference এবং @JsonBackReference এর উদাহরণ
উদাহরণ: Parent-Child Relationship
ধরা যাক, আমাদের একটি Person ক্লাস এবং একটি Address ক্লাস আছে। Person অবজেক্টে একটি Address অবজেক্ট রয়েছে এবং Address অবজেক্ট আবার Person কে রেফার করে (bi-directional relationship)। এটি Circular Reference তৈরি করবে।
কোড উদাহরণ:
import com.fasterxml.jackson.annotation.JsonManagedReference;
import com.fasterxml.jackson.annotation.JsonBackReference;
public class Person {
private String name;
@JsonManagedReference // Parent side of the relationship
private Address address;
// Constructors, Getters and Setters
public Person(String name, Address address) {
this.name = name;
this.address = address;
}
public String getName() {
return name;
}
public Address getAddress() {
return address;
}
}
public class Address {
private String street;
@JsonBackReference // Child side of the relationship
private Person person;
// Constructors, Getters and Setters
public Address(String street, Person person) {
this.street = street;
this.person = person;
}
public String getStreet() {
return street;
}
public Person getPerson() {
return person;
}
}
Serialization Example:
import com.fasterxml.jackson.databind.ObjectMapper;
public class JsonManagedBackReferenceExample {
public static void main(String[] args) throws Exception {
Address address = new Address("1234 Elm St", null);
Person person = new Person("John", address);
address = new Address("1234 Elm St", person);
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(person);
System.out.println(json);
}
}
JSON Output:
{
"name": "John",
"address": {
"street": "1234 Elm St"
}
}
ব্যাখ্যা:
@JsonManagedReferenceঅ্যানোটেশনটি Person অবজেক্টে ব্যবহার করা হয়েছে, যার মাধ্যমেAddressঅবজেক্টেরstreetফিল্ড JSON আউটপুটে দৃশ্যমান হয়েছে।@JsonBackReferenceঅ্যানোটেশনটি Address অবজেক্টে ব্যবহার করা হয়েছে, যার মাধ্যমেPersonরেফারেন্স JSON আউটপুটে প্রদর্শিত হয়নি।- Circular Reference সমস্যা এড়ানো হয়েছে, কারণ
Personঅবজেক্টের মধ্যে থাকাAddressঅবজেক্টটি ফ্ল্যাট হয়ে গেছে এবং এটি সঠিকভাবে সিরিয়ালাইজ হয়েছে।
@JsonManagedReference এবং @JsonBackReference এর সুবিধা
- Circular Reference থেকে মুক্তি:
- এ দুটি অ্যানোটেশন Circular References এড়াতে সাহায্য করে, যা JSON Serialization-এর সময় StackOverflow Error থেকে রক্ষা করে।
- Serialization Control:
- আপনি Control করতে পারেন কোন অবজেক্ট ফিল্ডটি JSON আউটপুটে থাকবে এবং কোনটি থাকবে না।
- Parent-Child Relationship:
- Parent-Child রিলেশনশিপের ক্ষেত্রে একে অপরকে রেফার করলেও, একপক্ষের অবজেক্টের ফিল্ড JSON আউটপুটে প্রদর্শিত হয়, অন্যটি শুধুমাত্র
@JsonBackReferenceএর মাধ্যমে ইনভিজিবল হয়ে যায়।
- Parent-Child রিলেশনশিপের ক্ষেত্রে একে অপরকে রেফার করলেও, একপক্ষের অবজেক্টের ফিল্ড JSON আউটপুটে প্রদর্শিত হয়, অন্যটি শুধুমাত্র
- Efficient Data Representation:
- Nested অথবা Circular Data Representations এড়ানো হয়, যা JSON ফাইলের আকার ছোট করে এবং ডেটা ব্যবস্থাপনাকে সহজ করে তোলে।
@JsonManagedReference এবং @JsonBackReference এর সীমাবদ্ধতা
- Bidirectional Relationships:
- যদি সম্পর্ক দুটি দিকে থাকে (bidirectional), তবে এগুলো কেবল একটি দিককে
@JsonManagedReferenceএবং অন্যটি@JsonBackReferenceহিসেবে চিহ্নিত করতে ব্যবহৃত হয়।
- যদি সম্পর্ক দুটি দিকে থাকে (bidirectional), তবে এগুলো কেবল একটি দিককে
- Complex Circular References:
- Jackson-এ আরও জটিল Circular References থাকলে, এই অ্যানোটেশনগুলি পুরোপুরি কার্যকর নাও হতে পারে। এর জন্য
@JsonIdentityInfoব্যবহার করা যেতে পারে।
- Jackson-এ আরও জটিল Circular References থাকলে, এই অ্যানোটেশনগুলি পুরোপুরি কার্যকর নাও হতে পারে। এর জন্য
- Single-direction Serialization:
- যদি আপনার প্রয়োজন হয় bidirectional Serialization এর, তবে
@JsonManagedReferenceএবং@JsonBackReferenceপুরোপুরি কাজ করবে না। অন্যভাবে, আপনাকে@JsonIdentityInfoব্যবহার করতে হতে পারে।
- যদি আপনার প্রয়োজন হয় bidirectional Serialization এর, তবে
@JsonManagedReference এবং @JsonBackReference এর বিকল্প
@JsonIdentityInfo:- Circular Reference সমস্যা সমাধানে আরও কার্যকর একটি বিকল্প। এটি object identity এর মাধ্যমে Circular Reference পরিচালনা করতে সাহায্য করে।
@JsonIdentityInfo উদাহরণ:
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public class Person {
private int id;
private String name;
// Constructors, Getters and Setters
}
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public class Address {
private int id;
private String street;
// Constructors, Getters and Setters
}
@JsonManagedReferenceএবং@JsonBackReferenceJackson এর অত্যন্ত কার্যকর অ্যানোটেশন, যা Circular Reference সমস্যার সমাধান করে এবং Parent-Child সম্পর্কের জন্য একটি একপক্ষীয় Serialization নিশ্চিত করে।@JsonManagedReferenceParent অবজেক্টে এবং@JsonBackReferenceChild অবজেক্টে ব্যবহার করতে হয়।- এই অ্যানোটেশনগুলি ব্যবহার করে, আমরা Circular References এবং Bidirectional Relationships JSON ডেটাতে সহজে এবং সঠিকভাবে ম্যানেজ করতে পারি।
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 এর ক্ষেত্রে।
Jackson ব্যবহার করে Parent-Child Relationship Mapping এর জন্য কিছু বিশেষ অ্যানোটেশন রয়েছে, যা আপনাকে Circular Reference সমস্যা সমাধান এবং Parent-Child Object গুলোকে সঠিকভাবে JSON আউটপুটে রূপান্তর করতে সাহায্য করে।
এখানে @JsonManagedReference এবং @JsonBackReference অ্যানোটেশন প্রধানভাবে ব্যবহার করা হয় Circular References হ্যান্ডেল করার জন্য। এছাড়াও, @JsonTypeInfo এবং @JsonSubTypes অ্যানোটেশন দিয়ে আপনি Polymorphic parent-child relationship mapping করতে পারেন।
1. Circular Reference Handling with @JsonManagedReference and @JsonBackReference
Circular Reference সমস্যা তখন ঘটে যখন দুটি অবজেক্ট একে অপরকে রেফার করে এবং এর ফলে অবিরাম রেফারেন্স তৈরি হয়, যার ফলে StackOverflowError হতে পারে। Jackson এ এই সমস্যা সমাধানে @JsonManagedReference এবং @JsonBackReference অ্যানোটেশন ব্যবহার করা হয়।
@JsonManagedReference: Parent Object-এর ফিল্ডের জন্য ব্যবহৃত হয় যা Child Object কে রেফার করে।@JsonBackReference: Child Object-এর ফিল্ডের জন্য ব্যবহৃত হয় যা Parent Object কে রেফার করে এবং এই ফিল্ডটি serialization-এর সময় ignore করা হয়।
উদাহরণ:
import com.fasterxml.jackson.annotation.JsonManagedReference;
import com.fasterxml.jackson.annotation.JsonBackReference;
public class Parent {
private String name;
@JsonManagedReference
private Child child;
// Constructors, Getters and Setters
}
public class Child {
private String name;
@JsonBackReference
private Parent parent;
// Constructors, Getters and Setters
}
Serialization Example:
import com.fasterxml.jackson.databind.ObjectMapper;
public class ParentChildSerialization {
public static void main(String[] args) throws Exception {
Parent parent = new Parent();
parent.setName("Rahim");
Child child = new Child();
child.setName("Rita");
parent.setChild(child);
child.setParent(parent);
ObjectMapper objectMapper = new ObjectMapper();
String json = objectMapper.writeValueAsString(parent);
System.out.println(json);
}
}
JSON Output:
{
"name": "Rahim",
"child": {
"name": "Rita"
}
}
ব্যাখ্যা:
@JsonManagedReferenceএবং@JsonBackReferenceঅ্যানোটেশনগুলির মাধ্যমে circular reference এড়ানো হয়েছে। এখানেchildঅবজেক্টকে flatten করা হয়েছে, কিন্তুparentঅবজেক্টে রেফারেন্স করাparentফিল্ডটি@JsonBackReferenceদ্বারা ignored হয়েছে।
2. Polymorphic Serialization with @JsonTypeInfo and @JsonSubTypes
Polymorphic parent-child relationship mapping এ Jackson এর @JsonTypeInfo এবং @JsonSubTypes অ্যানোটেশন সাহায্য করে, যা আপনাকে Inheritance Hierarchies (Parent এবং তার Subclass) সহজে serialize এবং deserialize করতে সাহায্য করে।
@JsonTypeInfo: এটি parent class এ ব্যবহার করা হয় এবং কোন subclass এর instance serialize/deserialze করা হবে তা নির্ধারণ করে।@JsonSubTypes: এটি parent class এ ব্যবহার করা হয় এবং কোন subclass গুলো serialize/deserialze হবে তা নির্ধারণ করে।
উদাহরণ:
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.JsonSubTypes;
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
@JsonSubTypes({
@JsonSubTypes.Type(value = Car.class, name = "car"),
@JsonSubTypes.Type(value = Truck.class, name = "truck")
})
abstract class Vehicle {
private String brand;
// Constructors, Getters and Setters
}
class Car extends Vehicle {
private int seatingCapacity;
// Constructors, Getters and Setters
}
class Truck extends Vehicle {
private int loadCapacity;
// Constructors, Getters and Setters
}
Serialization Example:
import com.fasterxml.jackson.databind.ObjectMapper;
public class VehicleSerialization {
public static void main(String[] args) throws Exception {
Vehicle car = new Car();
((Car) car).setSeatingCapacity(5);
((Car) car).setBrand("Toyota");
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(car);
System.out.println(json);
}
}
JSON Output:
{
"type": "car",
"brand": "Toyota",
"seatingCapacity": 5
}
ব্যাখ্যা:
@JsonTypeInfoএবং@JsonSubTypesব্যবহার করে Jackson এখানে Polymorphic objects serialize করতে সক্ষম হয়েছে।- JSON এর
typeফিল্ডের মাধ্যমে Jackson নির্ধারণ করতে পারে যে কোন subclass (Car বা Truck) serialize হবে।
3. Flattening Nested Objects with @JsonUnwrapped
@JsonUnwrapped অ্যানোটেশন ব্যবহার করে আপনি nested objects-এর ফিল্ডগুলোকে parent object এর অংশ হিসেবে flatten করতে পারেন, যা nested object কে JSON properties হিসেবে উপস্থাপন করে।
উদাহরণ:
import com.fasterxml.jackson.annotation.JsonUnwrapped;
public class Parent {
private String name;
@JsonUnwrapped
private Address address;
// Constructors, Getters and Setters
}
class Address {
private String street;
private String city;
private String zipCode;
// Constructors, Getters and Setters
}
Serialization Example:
import com.fasterxml.jackson.databind.ObjectMapper;
public class FlattenNestedObjects {
public static void main(String[] args) throws Exception {
Parent parent = new Parent();
parent.setName("Rahim");
Address address = new Address();
address.setStreet("123 Main St");
address.setCity("Dhaka");
address.setZipCode("1212");
parent.setAddress(address);
ObjectMapper objectMapper = new ObjectMapper();
String json = objectMapper.writeValueAsString(parent);
System.out.println(json);
}
}
JSON Output:
{
"name": "Rahim",
"street": "123 Main St",
"city": "Dhaka",
"zipCode": "1212"
}
ব্যাখ্যা:
@JsonUnwrappedব্যবহার করেAddressobject-এর ফিল্ডগুলোকে flatten করা হয়েছে, অর্থাৎParentobject-এর মধ্যেAddressobject-এর ফিল্ডগুলোকে直接 JSON properties হিসেবে রাখা হয়েছে।
4. Using @JsonProperty for Custom Field Naming
@JsonProperty অ্যানোটেশন ব্যবহার করে Parent-Child relationship এর মধ্যে JSON ফিল্ডের নাম কাস্টমাইজ করা যায়। এর মাধ্যমে আপনি প্রতিটি ফিল্ডের নাম কীভাবে JSON-এ প্রদর্শিত হবে তা নিয়ন্ত্রণ করতে পারেন।
উদাহরণ:
import com.fasterxml.jackson.annotation.JsonProperty;
public class Parent {
private String name;
@JsonProperty("address_info")
private Address address;
// Constructors, Getters and Setters
}
class Address {
private String street;
private String city;
private String zipCode;
// Constructors, Getters and Setters
}
JSON Output:
{
"name": "Rahim",
"address_info": {
"street": "123 Main St",
"city": "Dhaka",
"zipCode": "1212"
}
}
- Circular Reference সমস্যার সমাধান করতে
@JsonManagedReferenceএবং@JsonBackReferenceব্যবহার করুন। - Polymorphic Serialization-এর জন্য
@JsonTypeInfoএবং@JsonSubTypesব্যবহার করুন। - Flatten Nested Objects করতে
@JsonUnwrappedব্যবহার করুন। - Custom Field Naming এর জন্য
@JsonPropertyব্যবহার করুন। - Inheritance Mapping-এর জন্য Jackson annotations-এর মাধ্যমে Parent-Child relationship এর মধ্যে সঠিক serialization এবং deserialization সম্ভব।
Jackson এর @JsonManagedReference এবং @JsonBackReference অ্যানোটেশন দুটি Circular Reference সমস্যার সমাধান করতে ব্যবহৃত হয়, বিশেষত যখন এক ক্লাস অন্য ক্লাসের সাথে bi-directional relationship থাকে (যেমন Parent-Child)। এই অ্যানোটেশনগুলো একটি reference management সিস্টেম সরবরাহ করে, যা JSON Serialization এবং Deserialization-এর সময় circular references এড়াতে সাহায্য করে।
@JsonManagedReference এবং @JsonBackReference এর কার্যপদ্ধতি:
@JsonManagedReference: এটি Parent ক্লাসের সেই প্রপার্টি বা ফিল্ডে ব্যবহার করা হয়, যা child object রেফার করে।@JsonBackReference: এটি Child ক্লাসের সেই প্রপার্টি বা ফিল্ডে ব্যবহার করা হয়, যা parent object রেফার করে।
@JsonManagedReference এবং @JsonBackReference একে অপরের সাথে কাজ করে যাতে একটি circular reference JSON Serialization-এর সময় ব্লক না হয়।
প্র্যাকটিক্যাল উদাহরণ:
১. Parent এবং Child ক্লাস
ধরা যাক, একটি Person (Parent) এবং Address (Child) ক্লাসের মধ্যে bi-directional relationship রয়েছে। Person ক্লাসের একটি Address ফিল্ড রয়েছে, এবং Address ক্লাসের একটি Person ফিল্ড রয়েছে।
Person ক্লাস (Parent):
import com.fasterxml.jackson.annotation.JsonManagedReference;
public class Person {
private String name;
private Address address;
// Constructor
public Person(String name, Address address) {
this.name = name;
this.address = address;
}
// Getters and Setters
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@JsonManagedReference
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
}
Address ক্লাস (Child):
import com.fasterxml.jackson.annotation.JsonBackReference;
public class Address {
private String street;
private String city;
private Person person;
// Constructor
public Address(String street, String city, Person person) {
this.street = street;
this.city = city;
this.person = person;
}
// Getters and Setters
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
@JsonBackReference
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
}
Serialization Example:
import com.fasterxml.jackson.databind.ObjectMapper;
public class JsonManagedBackReferenceExample {
public static void main(String[] args) throws Exception {
// Address and Person Object Creation
Person person = new Person("John Doe", new Address("123 Elm St", "Springfield", null));
Address address = person.getAddress();
address.setPerson(person);
// Jackson ObjectMapper to convert to JSON
ObjectMapper objectMapper = new ObjectMapper();
String json = objectMapper.writeValueAsString(person);
System.out.println("Serialized JSON: " + json);
}
}
JSON Output:
{
"name": "John Doe",
"address": {
"street": "123 Elm St",
"city": "Springfield"
}
}
ব্যাখ্যা:
- এখানে,
@JsonManagedReferenceএবং@JsonBackReferenceব্যবহৃত হয়েছে Circular Reference সমস্যা প্রতিরোধ করার জন্য। @JsonManagedReferencePersonক্লাসেaddressফিল্ডে ব্যবহার করা হয়েছে, যা child অবজেক্টAddressরেফার করে।@JsonBackReferenceAddressক্লাসেpersonফিল্ডে ব্যবহার করা হয়েছে, যা parent অবজেক্টPersonরেফার করে।- এইভাবে,
addressএবংpersonপরস্পরের মধ্যে সঠিকভাবে রেফারেন্সিং সম্পন্ন হলেও Circular Reference তৈরি হয়নি।
@JsonManagedReference এবং @JsonBackReference এর অন্যান্য ব্যবহারের উদাহরণ:
Multiple Child Objects
আপনি যদি একাধিক child objects নিয়ে কাজ করেন, তাও এই অ্যানোটেশন ব্যবহার করা যেতে পারে।
import com.fasterxml.jackson.annotation.JsonManagedReference;
import java.util.List;
public class Department {
private String name;
@JsonManagedReference
private List<Employee> employees;
// Constructor, Getters, Setters
}
public class Employee {
private String name;
@JsonBackReference
private Department department;
// Constructor, Getters, Setters
}
Serialization Example:
import com.fasterxml.jackson.databind.ObjectMapper;
public class DepartmentEmployeeExample {
public static void main(String[] args) throws Exception {
Department dept = new Department("HR", List.of(new Employee("John", null), new Employee("Jane", null)));
dept.getEmployees().get(0).setDepartment(dept);
dept.getEmployees().get(1).setDepartment(dept);
// Jackson ObjectMapper to convert to JSON
ObjectMapper objectMapper = new ObjectMapper();
String json = objectMapper.writeValueAsString(dept);
System.out.println("Serialized JSON: " + json);
}
}
JSON Output:
{
"name": "HR",
"employees": [
{
"name": "John"
},
{
"name": "Jane"
}
]
}
@JsonManagedReference এবং @JsonBackReference এর সুবিধা:
- Circular Reference এড়ানো:
- JSON Serialization এবং Deserialization-এর সময় Circular References থেকে সমস্যা এড়াতে সহায়তা করে।
- Bidirectional Relationships Handling:
- Parent-Child রিলেশনশিপে সহজেই bi-directional reference manage করা যায়।
- Performance Optimization:
- একটি reference কে flat JSON আউটপুটে পরিবর্তন করা হয়, ফলে মেমোরি ব্যবহারে সাশ্রয় হয় এবং পারফরম্যান্স উন্নত হয়।
@JsonManagedReferenceএবং@JsonBackReferenceদুটি অ্যানোটেশন একসাথে ব্যবহার করা হয় bi-directional relationships-এর Circular Reference সমস্যা সমাধান করার জন্য।- এগুলি parent-child সম্পর্কের মধ্যে ডেটা সিরিয়ালাইজেশনে সহজ ও কার্যকর উপায় প্রদান করে, যেখানে একে অপরকে রেফার করা হয়।
- Jackson এর এই অ্যানোটেশন দুটি JSON প্রসেসিংকে আরও নিরাপদ, পরিষ্কার এবং কার্যকর করে তোলে।
Read more