如何使用Jackson在hibernate中处理双向一对一关系

我正在使用@JsonIgnore Annotation来为响应创建Json时防止无限循环,它可以正常工作,但是我想知道是否有一些替代方法,其中属性实际上没有被忽略,但也阻止了无限循环.

例如,我有entityA具有以下属性:

int id
String name
EntityB example;

和entityB有

int id
String something
EntityA entityAExample //(this one goes with the JsonIgnore)

因此,如果我获得entityA中的所有寄存器,响应将如下所示:

[{
    "id":"1",
    "name": "name",
    "entityB": {
                 "id":"1",
                 "something": "text"
               }
}]

而entityB将如下所示:

[{
   "id":"1",
   "something": "text"
}]

它适用于我目前所需要的,但我希望实体B也可以包含entityA(或者列表,如果是多对一关系),所以响应如下:

[{
    "id":"1",
    "something": "text",
    "entityAExample": {
                      "id":"1",
                      "name": "name"
                      }
}]

所以,无论我查询哪个实体,它都会显示相关记录.

最佳答案 在处理json时,这是一个常见的双向关系问题.

我认为与Jackson解决这个问题的最简单方法是使用@JsonIdentityInfo.您只需要使用以下内容注释您的类:

@Entity
@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id")
public class EntityA{
    ...
}

@Entity
@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id")
public class EntityB{
    ...
}

这样做的是,当一个之前已经被序列化的实体,即父实体(EntityA),必须第二次序列化时才开始无限递归循环,它不会像往常一样被序列化.

相反,它将使用您在注释中指定的属性(即id)进行序列化.

简而言之,注释允许您指定对象的替代表示,该表示仅在实体启动无限循环时使用,从而打破该循环.

按照您的示例,将导致:

[{
    "id":"1",
    "name": "name",
    "entityB": {
                 "id":"2",
                 "something": "text"
                 "entityAExample": "1"                                       
               }
}]

您还可以仅注释EntityB而不是两个实体,这将导致:

[{
    "id":"1",
    "name": "name",
    "entityB": {
                 "id":"2",
                 "something": "text"
                 "entityAExample": {
                                    "id": "1",
                                    "name": "name",
                                    "entityBExample": "2"                                         
                                   }
               }
}]

您也可以使用其他属性,但’id’通常可以正常工作. Here’s官方文档和wiki.

Here’s一篇文章更详细地解释了这一点,而another则展示了解决它的其他方法.

点赞