Feature: Object Identity (or Object Identifier / Object Id)

(see Jira entry JACKSON-107 for details)

Background

Before Jackson 2.0, handling of cyclic object graphs (or, more generally, that of shared references) was limited to specific case of parent/child (bi-directional) references. While this could be used to support straight-forward one-to-many and one-to-one references that are common with database models, it is not a general solution.

Since 2.0 allowed bigger changes to API and internal interfaces, more general solution was planned for this release

General Approach

At high level, there are two major alternatives for handling Object Identity:

Benefit of the first approach is that it would be universal, and work for general Java Object serialization use case. The big downsides include:

Conversely, second approach has opposite benefits/drawbacks:

Chosen Approach

Given these trade-offs, it seemed more feasible to use approach of requiring explicit enabling of Object Identity handling. In the first phase (2.0), all types must be explicitly annotated (possibly with mix-ins); although this could be extended to allow "default Object Identity", similar to how "default typing" can be used with Type Id.

New annotation: @JsonIdentityInfo

Whether Object Identity information is to be used for determining how to serialize/deserialize property value to/from JSON (and other data formats) will be based on existence (or lack thereof) of @JsonIdentityInfo annotation. It can be used on classes (to indicate that properties of that type should have feature enabled) as well as on individual properties (to support cases where type itself can not be annotated; or to use different id generation sequence).

A simple example would be:

@JsonIdentityInfo(generator=ObjectIdGenerators.IntSequenceGenerator.class, property="@id")
public class Identifiable
{
    public int value;

    public Identifiable next;
}

and if we created a cycle consisting of two values, like:

  Identifiable ob1 = new Identifiable();
  ob1.value = 13;
  Identifiable ob2 = new Identifiable();
  ob2.value = 42;
  // link as a cycle:
  ob1.next = ob2;
  ob2.next = ob1;

and serialized using:

  String json = objectMapper.writeValueAsString(ob1);

we would get following serialization for JSON:

  {
    "@id" : 1,
    "value" : 13,
    "next" : {
       "@id" : 2,
       "value" : 42,
       "next" : 1
     }
  }

This example shows couple of notable things:

Finally: we would deserialize such JSON using usual calls:

  Identifiable result = objectMapper.readValue(json, Identifiable.class);


CategoryJackson

JacksonFeatureObjectIdentity (last edited 2012-07-05 15:08:36 by TatuSaloranta)

Copyright ©2009 FasterXML, LLC