我有 2 張桌子 - 放映 (ManyToOne) 和房間 (OneToMany)。當我在房間存盤庫上使用 findAll 時,它會回傳一個帶有放映資料的 json,但是當我以相反的方式(screenings.findAll)這樣做時,它不會回傳房間。在模型篩選中,我有關系:
@ManyToOne
@JoinColumn(name = "room_id")
@JsonBackReference
private Room room;
在房間模型中:
@OneToMany(mappedBy="room")
@JsonManagedReference
private List<Screening> screenings;
ScreeningService 包含:
@Autowired
public ScreeningService(ScreeningRepository screeningRepository) {
this.screeningRepository = screeningRepository;
}
public List<Screening> getScreenings(){
return screeningRepository.findAll();
}
并且回傳值沒有 Room 模型:
{
"id": 1,
"startDate": "2022-06-20T13:00:00.000 00:00",
"endDate": "2022-06-20T15:00:00.000 00:00"
},
{
"id": 2,
"startDate": "2022-06-20T13:15:00.000 00:00",
"endDate": "2022-06-20T15:15:00.000 00:00"
},
當我以相反的方式這樣做并打電話時
public List<Room> getRooms() {
return roomRepository.findAll();
}
結果與我想要的完全相同:
{
"id": 2,
"number": 2,
"screenings": [
{
"id": 2,
"startDate": "2022-06-20T13:15:00.000 00:00",
"endDate": "2022-06-20T15:15:00.000 00:00"
},
{
"id": 5,
"startDate": "2022-06-20T13:15:00.000 00:00",
"endDate": "2022-06-20T15:15:00.000 00:00"
},
{
"id": 7,
"startDate": "2022-06-20T18:15:00.000 00:00",
"endDate": "2022-06-20T21:15:00.000 00:00"
}
]
},
這可能會做還是我做錯了什么?
uj5u.com熱心網友回復:
問題在于 JSON 序列化級別。
你有一個雙向的關系!
如果您將默認序列化這些物件而不使用額外的注釋(@JsonManagedReference,@JsonBackReference),您將得到StackOverflowError例外。原因是杰克遜通過雙向關系進入了無限遞回。
因此,要解決杰克遜 JSON 無限遞回問題,您使用了 @JsonManagedReference和@JsonBackReference。注釋的主要思想是將關系分為兩部分:父級和子級。
@JsonManagedReference是參考的父(或“轉發”)部分——正常序列化的部分。
@JsonBackReference是參考的子(或“后”)部分——它將從序列化中省略。
所以杰克遜只會序列化一個關系部分,永遠不會進入無限回圈。你可以在你的例子中看到它。
或者,我們也可以使用@JsonIgnore注釋來簡單地忽略關系的一側,從而破壞鏈。
如果您希望能夠從雙方序列化物件:
解決方案:注釋 JsonIdentityInfo
用于指示帶注釋的型別或屬性的值應該是序列化的注釋,以便實體包含額外的物件識別符號(除了實際的物件屬性),或者作為由參考完整序列化的物件 id 組成的參考。在實踐中,這是通過將第一個實體序列化為完整的物件和物件標識,以及對物件的其他參考作為參考值來完成的。
從您的物體中洗掉@JsonManagedReference,@JsonBackReference注釋。
將類級別注釋添加到Screening物體:
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
property = "id")
public class Screening { ... }
將類級別注釋添加到Room物體:
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
property = "id")
public class Room { ... }
Room物體的輸出:
{
"id": 2,
"number": 2,
"screenings": [
{
"id": 2,
"startDate": "2022-06-20T13:15:00.000 00:00",
"endDate": "2022-06-20T15:15:00.000 00:00",
"room": 2
},
{
"id": 5,
"startDate": "2022-06-20T13:15:00.000 00:00",
"endDate": "2022-06-20T15:15:00.000 00:00",
"room": 2
},
{
"id": 7,
"startDate": "2022-06-20T18:15:00.000 00:00",
"endDate": "2022-06-20T21:15:00.000 00:00",
"room": 2
}
]
}
Screening物體的輸出:
{
"id": 2,
"startDate": "2022-06-20T13:15:00.000 00:00",
"endDate": "2022-06-20T15:15:00.000 00:00",
"room": {
"id": 2,
"number": 2,
"screenings": [2,5,7]
}
}
如果默認行為@JsonIdentityInfo不適合您的用例,您可以創建自定義序列化程式并自行處理雙向問題。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/464397.html
上一篇:反應路由器v6路由問題
