【问题标题】:How to handle bidirectional one to one relationship in hibernate with Jackson如何在与杰克逊的休眠中处理双向一对一关系
【发布时间】:2016-04-04 14:33:02
【问题描述】:

我在为响应创建 Json 时使用@JsonIgnore Annotation 来防止无限循环,它可以很好地满足我的需要,但我想知道是否有一些替代方案实际上没有忽略该属性还可以防止无限循环。

例如,我的 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 也可以包含实体 A(或列表,如果是多对一关系),因此响应如下所示:

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

因此,无论我查询哪个实体,它都会始终显示相关记录。

【问题讨论】:

    标签: java json hibernate jackson


    【解决方案1】:

    这是处理 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 一篇文章展示了其他解决方法。

    【讨论】:

    • 我尝试使用解释的解决方案,但是在生成 json 时出现 java 堆空间错误:java.lang.OutOfMemoryError: Java heap space
    • 这不会阻止递归。您在上面链接到的 Baeldung 文章中的大多数想法也不起作用。似乎唯一有效的是@JsonIgnore
    猜你喜欢
    • 1970-01-01
    • 2017-06-06
    • 1970-01-01
    • 2019-04-16
    • 2016-01-20
    • 2017-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多