Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Java

Khi nào dùng @JsonManagedReference và @JsonBackReference (Jackson)

Hai annotation này xử lý **bidirectional relationship** (quan hệ hai chiều) tránh circular reference khi serialize. Cách tiếp cận khác với @JsonIdentityInfo.

  • @JsonManagedReference: **Forward reference** - được serialize bình thường.
  • @JsonBackReference: **Back reference** - **bỏ qua** khi serialize (omit).

Ví dụ: Manager ↔ Employee (Bidirectional)

import com.fasterxml.jackson.annotation.*;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.*;

public class ManagedBackRefTest {
    public static void main(String[] args) throws Exception {
        ObjectMapper mapper = new ObjectMapper();
        
        BackReferenceBean manager = new BackReferenceBean(110, "Sai Chaitanya");
        ManagedReferenceBean emp = new ManagedReferenceBean(135, "Adithya Ram", manager);
        manager.addEmployees(emp);
        
        // Serialize từ Employee (managed side)
        String json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(emp);
        System.out.println(json);
    }
}

class ManagedReferenceBean {
    public int empId = 115;
    public String empName = "Raja Ramesh";
    
    @JsonManagedReference
    public BackReferenceBean manager; // Forward: serialize manager
    
    public ManagedReferenceBean(int id, String name, BackReferenceBean mgr) {
        this.empId = id; this.empName = name; this.manager = mgr;
    }
}

class BackReferenceBean {
    public int empId = 125;
    public String empName = "Jai Dev";
    
    @JsonBackReference
    public List<ManagedReferenceBean> list = new ArrayList<>(); // Back: KHÔNG serialize list
    
    public BackReferenceBean(int id, String name) {
        this.empId = id; this.empName = name;
    }
    public void addEmployees(ManagedReferenceBean e) { list.add(e); }
}

Output

{
  "empId" : 135,
  "empName" : "Adithya Ram",
  "manager" : {
    "empId" : 110,
    "empName" : "Sai Chaitanya"
  }
}

Field list trong Manager **không xuất hiện** trong JSON (do @JsonBackReference).

Quy tắc đặt annotation

  • Đặt @JsonManagedReference ở phía "owner" hoặc phía thường được serialize trước.
  • Đặt @JsonBackReference ở phía "inverse" (collection hoặc back-pointer).
  • Cặp annotation phải cùng **logical name** (mặc định là property name) hoặc chỉ định value="name".

So sánh với @JsonIdentityInfo

Đặc điểm @ManagedReference/@BackReference @JsonIdentityInfo
Cách hoạt động Omit back-reference hoàn toàn Serialize full lần đầu, sau dùng ID reference
Output Tree structure (không lặp) Có @id/@ref cho object lặp
Deserialize Không restore back-reference tự động Tự restore full object graph
Phù hợp Chỉ cần serialize one-way Cần round-trip serialize/deserialize

Lưu ý

  • @JsonBackReference field sẽ **null** sau deserialize (Jackson không populate).
  • Cần logic thủ công để rebuild back-reference nếu cần.
  • Jackson 2.12+: Có @JsonIdentityReference (alwaysAsId) cho linh hoạt hơn.