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.