Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Java

เมื่อไหร่ควรใช้ @JsonManagedReference และ @JsonBackReference ใน Jackson (Java)

คำอธิบายประกอบ @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 ที่ไม่ต้องการข้อมูลกลับมา