Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jackson confused with bidirectional one-to-many relationship

Tags:

json

jackson

I'm using jackson 1.9.2 with Hibernate/Spring MVC through MappingJacksonHttpMessageConverter.

Jackson can not serialize bidirectional one-to-many relationship and makes an infinite loop.

The classes I'm using are :

  • Conversation which has a Set of SMS instances.

  • Each SMS instance has a Set of PhoneNumbers

  • Each PhoneNumber has a parent contact (this is the bidirectional many-to-one relationship)

What I am trying to do is to serialize a conversation.

If I don't use @JsonManagedReference and @JsonBackReference then jackson will crashe due to an infinite loop. But when I use them, the Contact doesn't get serialized into the PhoneNumber.

Class Contact {
  @JsonManagedReference
  List<PhoneNumber> phoneNumber ;
}
Class PhoneNumber {
  @JsonBackReference 
  Contact contact;
}

The output is :

{    <--------------------- Conversation
    "id": 51,
    "smsSet": [
      {
        "id": 53,
        "origin": 0123465,
        "destination": "06533844XY",
        "message": "Hello world!",
        "phoneNumbers": [
          {
            "id": 64,
            "num": "06533844XY",
            "creationDate": 1333992533000,
          }
        ],
      }
    ],
    "creationDate": 1333992534000
  }

instead of

{    <---------- conversation
    "id": 51,
    "smsSet": [
      {
        "id": 53,
        "origin": 0123465,
        "destination": "06533844XY",
        "message": "Hello world!",
        "phoneNumbers": [
          {
            "id": 64,
            "num": "06533844XY",
            "creationDate": 1333992533000,
            "contact":  <--------------------- Missing part
             {
                "id": 12,
                "name": "Samuel Jackson",
                "primaryNumber": "06533844XY"
             }
          }
        ],
      }
    ],
    "creationDate": 1333992534000
  }
like image 890
redochka Avatar asked Apr 10 '12 23:04

redochka


1 Answers

I recently encountered a similar problem: Jackson - serialization of entities with birectional relationships (avoiding cycles)

So the solution is to upgrade to Jackson 2.0, and add to classes the following annotation:

@JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class, 
                  property = "@id")
public class SomeEntityClass ...

Then the problem is that Spring doesn't work with Jackson 2.0. This has been solved in the following way:

<bean id="jacksonMessageConverter"
          class="own.implementation.of.MappingJacksonHttpMessageConverter"/>

<bean class="org.springframework.web.servlet.mvc
             .annotation.AnnotationMethodHandlerAdapter">
        <property name="messageConverters">
            <list>
                <ref bean="jacksonMessageConverter"/>
            </list>
        </property>
        <property name="requireSession" value="false"/>
    </bean>

And the own.implementation.of.MappingJacksonHttpMessageConverter is based on this:

http://www.jarvana.com/jarvana/view/org/springframework/spring-web/3.0.0.RELEASE/spring-web-3.0.0.RELEASE-sources.jar!/org/springframework/http/converter/json/MappingJacksonHttpMessageConverter.java?format=ok

But use ObjectMapper and other Jackson classes from Jackson 2.0 instead of Jackson 1.*

like image 148
Eugene Retunsky Avatar answered Nov 07 '22 00:11

Eugene Retunsky