JPA實體聚合關係導致jackson迴圈解析實體的解決
問題描述:當我們使用JPA聚合關係:多對多(@ManyToMany),多對一(@ManyToOne)(一對多)這兩種關係管理實體時,Controller裡採用@ResponseBody返回實體時(@OneToOne沒事),會發生迴圈解析實體,可能導致產生的資料錯誤或者後臺異常。
例如:員工(Staff) 、部門(Department) 、專案(Project)
Staff和Department關係:@ManyToOne(多個員工屬於一個部門)
Department和Staff關係:@OneToMany(一個部門有多個員工)
Staff和Project關係:@ManyToMnay(一個員工可能忙多個專案,一個專案也可能含多個員工)
當我們RestController層通過id查詢單個員工時,返回Staff實體的json時,就會產生問題(以多對一關係為例子):
Json解析Staff類:Staff類包含Department類(@ManyToOne),然後去解析Staff裡的Department類,結果Department裡還有Staff實體(@OneToMany),又返回來解析Staff實體,Staff類又包含Department類....造成死迴圈。
問題解決:
其實我們可以換個思路去思考這個問題:
(1)我們獲取一個員工(Staff)資訊時,關不關心他的部門(Department)是什麼,他在忙什麼專案(Project)。
(2)當我們獲取一個部門資訊時,關不關心部門下所有的員工資訊。
我覺得我比較關心(1),不太關心(2),不關心(2)的原因是,如果我想獲取一個部門下的所有員工時,我可以單獨去查這個部門的所有員工,而沒必要去獲取部門資訊時就把所有員工資訊都返回。
jackson也為我們設定了這樣的註解:@JsonManagedReference @JsonBackReference
@JsonManagedReference:引用的管理方
@JsonBackReference:返回引用管理方
我們把@JsonManagedReference放到Staff類的Department屬性上同時把@JsonBackReference放到Department類的List<Staff>屬性上,就是告訴jackson不要迴圈解析啦,Staff是管理方要展示Department,而Department要返回引用管理方。最後的結果就是Staff的json裡含Department的資訊,如果單獨查詢Department實體時不會出現Staff的資訊。