1

Ok, so I'm trying to test some stuffs with jackson json converter. I'm trying to simulate a graph behaviour, so these are my POJO entities

@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public class ParentEntity implements java.io.Serializable
{   
    private String id;
    private String description;
    private ParentEntity parentEntity;
    private List<ParentEntity> parentEntities = new ArrayList<ParentEntity>(0);
    private List<ChildEntity> children = new ArrayList<ChildEntity>(0);
    // ... getters and setters
}

@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public class ChildEntity implements java.io.Serializable
{
    private String id;
    private String description;
    private ParentEntity parent;
    // ... getters and setters
}

The tags are required in order to avoid exception on serialization. When I try to serialize an object (both on a file or on a simple string) all works fine. However, when I try to deserialize the object, it throws an exception. This is the simple test method (try/catch omitted for simplicity)

{
    // create some entities, assigning them some values
    ParentEntity pe = new ParentEntity();
    pe.setId("1");
    pe.setDescription("first parent");

    ChildEntity ce1 = new ChildEntity();
    ce1.setId("1");
    ce1.setDescription("first child");
    ce1.setParent(pe);

    ChildEntity ce2 = new ChildEntity();
    ce2.setId("2");
    ce2.setDescription("second child");
    ce2.setParent(pe);

    pe.getChildren().add(ce1);
    pe.getChildren().add(ce2);

    ParentEntity pe2 = new ParentEntity();
    pe2.setId("2");
    pe2.setDescription("second parent");
    pe2.setParentEntity(pe);
    pe.getParentEntities().add(pe2);

    // serialization
    ObjectMapper mapper = new ObjectMapper();
    File f = new File("parent_entity.json");
    // write to file
        mapper.writeValue(f, pe);
    // write to string
    String s = mapper.writeValueAsString(pe);
    // deserialization
    // read from file
    ParentEntity pe3 = mapper.readValue(f,ParentEntity.class);
    // read from string
    ParentEntity pe4 = mapper.readValue(s, ParentEntity.class);         
}

and this is the exception thrown (of course, repeated twice)

com.fasterxml.jackson.databind.JsonMappingException: Already had POJO for id (java.lang.String) [com.fasterxml.jackson.annotation.ObjectIdGenerator$IdKey@3372bb3f] (through reference chain: ParentEntity["children"]->java.util.ArrayList[0]->ChildEntity["id"])
...stacktrace...
Caused by: java.lang.IllegalStateException: Already had POJO for id (java.lang.String) [com.fasterxml.jackson.annotation.ObjectIdGenerator$IdKey@3372bb3f]
...stacktrace...

So, what is the cause of the problem? How can I fix it? Do I need some other annotation?

tigerjack
  • 1,158
  • 3
  • 21
  • 39

1 Answers1

2

Actually, it seems that the problem was with the "id" property. Because the name of the property is equal for the two different entities, there were some problems during deserialization. Don't know if it makes sense at all, but I solved the problem changing the JsonIdentityInfo tag of ParentEntity to

@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property = "id", scope = ParentEntity.class))

Of course, I also changed the scope of ChildEntity with scope=ChildEntity.class as suggested here

I'm open to new answer and suggestions by the way.

Community
  • 1
  • 1
tigerjack
  • 1,158
  • 3
  • 21
  • 39
  • Thank you for the information. you can add also this line mapper.configure(SerializationFeature.INDENT_OUTPUT, true); to configure Object mapper for pretty print – JHDev Nov 02 '14 at 16:29
  • 1
    In addition to the above, I also found other additional features on fasterxml site -to allow serialization of "empty" POJOs (no properties to serialize) (without this setting, an exception is thrown in those cases) `mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);` -to write java.util.Date, Calendar as number (timestamp): `mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);` – tigerjack Nov 02 '14 at 16:35