春季数据JPA- Findall不返回关系数据
我有2个桌子 - 放映(许多人)和房间(Onetomany)。当我在房间存储库上使用Findall时,它会将我的JSON返回带有屏幕数据的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();
}
返回的值没有房间模型:
{
"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"
}
]
},
可以做或我做错事?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
问题在于JSON序列化级别。
您有双向关系!
如果您默认情况下将这些对象序列化,而无需其他注释(
@jsonmanagedReference
,@jsonbackReference
),您将获得StackoverFlowerRorRor
exception。原因是杰克逊通过双向关系进入无限的递归。因此,要解决Jackson Json Infinite Recursion问题,您使用了 @jsonmanagedReference , @jsonbackReference 。注释的主要思想是,关系将分为两个部分:父母和孩子。
是参考的父(或“向前”)部分 - 正常序列化的一个。
是参考的儿童(或“背部”)部分 - 将从序列化中省略它。
因此,杰克逊将仅序列化一个关系部分,而永远不会进入无限循环。您可以在示例中看到它。
另外,我们还可以使用 @jsonignore 注释只是简单地忽略了关系的一个方面,从而破坏了链条。
如果您想具有从双方序列化对象的能力:
解决方案:
删除
@jsonmanagedReference
,@jsonbackReference
您的实体注释。将类级注释添加到
筛选
实体:将类级注释添加到
ROOM
实体:ROOM> ROOM
实体的输出:筛选实体:
如果
@jsonidentityinfo
的默认行为不适合您的用例how-do-i-us-a-a-custom-serializer-with-jackson>自定义序列化器并自己处理双向问题。The problem is on JSON serialization level.
You have a bidirectional relationship!
If you will serialize these objects by default without additional annotations(
@JsonManagedReference
,@JsonBackReference
) you will getStackOverflowError
exception. The reason is that Jackson gets into infinite recursion by the bidirectional relationship.So to resolve Jackson JSON infinite recursion problem you used @JsonManagedReference, @JsonBackReference. The main idea of annotations is that relation will be split into two parts: parent and child.
@JsonManagedReference is the parent (or "forward") part of the reference – the one that gets serialized normally.
@JsonBackReference is the child (or "back") part of the reference – it will be omitted from serialization.
So Jackson will serialize only one relation part and never gets into the infinity loop. You can see it in your example.
Alternatively, we can also use the @JsonIgnore annotation to simply ignore one of the sides of the relationship, thus breaking the chain.
In case you want to have the ability to serialize objects from both sides:
Solution: Annotation JsonIdentityInfo
Remove
@JsonManagedReference
,@JsonBackReference
annotations from your entities.Add the class level annotation to
Screening
entity:Add the class level annotation to
Room
entity:The output of
Room
entity:The output of
Screening
entity:In case the default behavior of
@JsonIdentityInfo
does not fit your use case, you can create Custom Serializer and handle bidirectional problem on your own.