คำอธิบายประกอบ @JsonManagedReference และ @JsonBackReference ใช้สร้าง JSON structure แบบ bidirectional (สองทิศทาง) @JsonManagedReference เป็น forward reference ที่รวมเข้าไปใน serialization ในขณะที่ @JsonBackReference เป็น back reference ที่ละเว้น (omit) ระหว่าง serialization
ตัวอย่างการใช้งาน
import java.util.*;
import com.fasterxml.jackson.annotation.JsonManagedReference;
import com.fasterxml.jackson.annotation.JsonBackReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.core.JsonProcessingException;
public class ManagedReferenceBackReferenceTest {
public static void main(String args[]) throws JsonProcessingException {
BackReferenceBeanTest testBean = new BackReferenceBeanTest(110, "Sai Chaitanya");
ManagedReferenceBeanTest bean = new ManagedReferenceBeanTest(135, "Adithya Ram", testBean);
testBean.addEmployees(bean);
ObjectMapper mapper = new ObjectMapper();
String jsonString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(bean);
System.out.println(jsonString);
}
}
class ManagedReferenceBeanTest {
public int empId = 115;
public String empName = "Raja Ramesh";
@JsonManagedReference
public BackReferenceBeanTest manager;
public ManagedReferenceBeanTest(int empId, String empName, BackReferenceBeanTest manager) {
this.empId = empId;
this.empName = empName;
this.manager = manager;
}
}
class BackReferenceBeanTest {
public int empId = 125;
public String empName = "Jai Dev";
@JsonBackReference
public List<ManagedReferenceBeanTest> list;
public BackReferenceBeanTest(int empId, String empName) {
this.empId = empId;
this.empName = empName;
this.list = new ArrayList<>();
}
public void addEmployees(ManagedReferenceBeanTest managedReferenceBeanTest) {
list.add(managedReferenceBeanTest);
}
}
ผลลัพธ์ (Output)
{
"empId" : 135,
"empName" : "Adithya Ram",
"manager" : {
"empId" : 110,
"empName" : "Sai Chaitanya"
}
}
คำอธิบาย
ในตัวอย่าง ManagedReferenceBeanTest มี reference ไป BackReferenceBeanTest (manager) ซึ่งถูก annotate @JsonManagedReference - จะถูก serialize ปกติ ส่วน BackReferenceBeanTest มี list ของ ManagedReferenceBeanTest ซึ่งถูก annotate @JsonBackReference - จะถูกละเว้นระหว่าง serialize
ผลคือ เมื่อ serialize ManagedReferenceBeanTest จะได้ manager object สมบูรณ์ แต่เมื่อ serialize BackReferenceBeanTest (ถ้า serialize ตรงๆ) จะไม่ได้ list ของ employees กลับมา
กรณีการใช้งาน (Use Cases)
- Parent-Child relationship - Parent มี list of children, Child มี reference กลับ parent
- Employee-Manager - Employee มี manager, Manager มี list ของ subordinates
- Order-OrderLine - Order มี lines, Line มี reference กลับ order
- ความสัมพันธ์ bidirectional ใดๆ ที่ต้องการ serialize แค่ทิศทางเดียว
ตัวเลือกอื่น: @JsonIdentityInfo
สำหรับกรณีที่ต้องการ serialize ทั้งสองทิศทางแต่ไม่ให้ infinite recursion ให้ใช้ @JsonIdentityInfo (ดูบทความก่อนหน้า) แทน ซึ่งจะใช้ object ID แทนการ serialize ซ้ำ
สรุป
@JsonManagedReference/@JsonBackReference เป็นคู่ที่ใช้จัดการ bidirectional relationship แบบ simple: serialize ทิศทาง forward, ignore ทิศทาง back เหมาะสำหรับ parent-child hierarchy ที่ไม่ต้องการข้อมูลกลับมา