如何用Jackson处理休眠中的双向一对一关系 [英] How to handle bidirectional one to one relationship in hibernate with Jackson

查看:107
本文介绍了如何用Jackson处理休眠中的双向一对一关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用 @JsonIgnore Annotation来防止为响应创建Json时的无限循环,并且它适用于我需要的,但我想知道例如,我有 entityA ,其中包含以下属性:

  int id 
字符串名称
EntityB示例;

entityB

  int id 
字符串
EntityA entityAExample //(这是一个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:文本
entityAExample:1
}
}]

您也可以只注释EntityB而不是两个实体,这会导致:

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



<您可以使用其他属性,尽管'id'通常可以正常工作。 这里是官方文档和 wiki



这里有一篇文章更详细地解释了这一点,一个显示其他解决方法的方法。另一个显示其他解决方法。


I'm using @JsonIgnore Annotation to prevent infinite loops when creating the Json for the responses and it works fine for what I need, but I'd like to know if there is some alternative where the property is not actually ignored but also prevents the infinite loop.

For example, I have entityA with following properties:

int id
String name
EntityB example;

and entityB has

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

So if I get all the registers in entityA, response will look like this:

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

And entityB will look like:

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

It works good for what I need so far, but I'd like that entity B could also include the entityA (or the list if is a many to one relationship) so the response look like:

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

So, doesn't matter which entity I query, it will always show the related records.

解决方案

This is a common bidirectional relationships problem when dealing with json.

I think the easiest way of solving this with Jackson is using @JsonIdentityInfo. You just need to annotate your classes with something like this:

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

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

What this does is that when an entity that has already been serialized before, that's the parent entity (EntityA), has to be serialized a second time starting the infinite recursion loop, it will not be serialized as usual.

Instead it will be serialized using the property that you specified in the annotation, that is the id.

In short, the annotation lets you specify an alternative representation of the object that will only be used when the entity starts an infinite loop, thus breaking that loop.

Following your example that would result in:

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

You could also annotate only EntityB instead of both entities and that would result in:

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

You can use other properties too altough the 'id 'usually works fine. Here's the the official documentation and the wiki.

Here's an article explaining this in more detail and another one showing other ways of solving it.

这篇关于如何用Jackson处理休眠中的双向一对一关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆