Deserialize Json Array that contin 2 objects with the same ID - JsonMappingException: Already had POJO for id
See original GitHub issueHow can I deserialize an Array with two objects that contains the same SubObject with the same Id?
For example this is the JSON of the array
[
{
"@id": 98,
"age": 29,
"name": "mkyong",
"relatedPackage": {"@id":99, "receivedOn":1374012807237 }
},
{
"@id": 101,
"age": 25,
"name": "luis",
"relatedPackage": {"@id":99, "receivedOn":1374012807237 }
}
]
As you can see both objects has the same related package. I want that the deserializer only parse the first relatedPackage and use it for the secon relatedPackage.
My Pojos are the next:
User Class:
package com.mkyong.core;
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
@JsonIdentityInfo(generator=ObjectIdGenerators.IntSequenceGenerator.class,property="@id")
public class User {
public int age;
public String name;
public RelatedPackage relatedPackage;
//getter and setter methods
@Override
public String toString() {
return "User [age=" + age + ", name=" + name + ", " +
"messages=" + relatedPackage + "]";
}
}
RelatedPackage Class:
package com.mkyong.core;
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
@JsonIdentityInfo(generator=ObjectIdGenerators.IntSequenceGenerator.class,property="@id")
public class RelatedPackage {
public long receivedOn;
public String toString() {
return "{ receivedOn: " + receivedOn + " }";
}
}
And finaly the main Object wich realize the deserializtion:
package com.mkyong.core;
import java.io.File;
import java.io.IOException;
import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class JacksonExample {
public static void main(String[] args) {
ObjectMapper mapper = new ObjectMapper();
try {
// read from file, convert it to user class
File file = new File("/home/lvargas/user.json");
User[] userList = mapper.readValue(file, User[].class);
// display to console
System.out.println(userList);
} catch (JsonGenerationException e) {
e.printStackTrace();
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
When both relatedPackage has the same Id it sends me the next error message
com.fasterxml.jackson.databind.JsonMappingException: Already had POJO for id (java.lang.Integer) [99] (through reference chain: com.mkyong.core.User["relatedPackage"]->com.mkyong.core.RelatedPackage["@id"])
at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:232)
at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:197)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.wrapAndThrow(BeanDeserializerBase.java:1332)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:252)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:115)
at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:449)
at com.fasterxml.jackson.databind.deser.impl.FieldProperty.deserializeAndSet(FieldProperty.java:107)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:250)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:115)
at com.fasterxml.jackson.databind.deser.std.ObjectArrayDeserializer.deserialize(ObjectArrayDeserializer.java:151)
at com.fasterxml.jackson.databind.deser.std.ObjectArrayDeserializer.deserialize(ObjectArrayDeserializer.java:18)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:2888)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:1988)
at com.mkyong.core.JacksonExample.main(JacksonExample.java:20)
Caused by: java.lang.IllegalStateException: Already had POJO for id (java.lang.Integer) [99]
at com.fasterxml.jackson.databind.deser.impl.ReadableObjectId.bindItem(ReadableObjectId.java:27)
at com.fasterxml.jackson.databind.deser.impl.ObjectIdValueProperty.deserializeSetAndReturn(ObjectIdValueProperty.java:91)
at com.fasterxml.jackson.databind.deser.impl.ObjectIdValueProperty.deserializeAndSet(ObjectIdValueProperty.java:80)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:250)
... 10 more
I understand that it is trying to create a second object with the same objectId.
How can I solve that problem?
Issue Analytics
- State:
- Created 10 years ago
- Comments:35 (14 by maintainers)
Top Results From Across the Web
Deserialize Json Array that contin 2 objects with the same ID
I want that the deserializer only parse the first relatedPackage and use it for the secon relatedPackage. My Pojos are the next: User...
Read more >Unable to deserialize Json that contain 2 objects with the ...
I have used jackson JsonIdentityInfo to handle the recursive object reference in spring mvc. I came across one issue i.e., Unable to deserialize...
Read more >DeserializationFeature (jackson-databind 2.11.0 API)
Enumeration that defines simple on/off features that affect the way Java objects are deserialized from JSON. Note that features can be set both...
Read more >All You Need To Know About JSON Parsing With Jackson
It allows us to do conversion between POJOs and JSON documents using property accessors or using annotations. It offers two types of binding:....
Read more >Line-delimited JSON with Jackson - cowtowncoder - Medium
JSON specification defines “JSON Values” as just “[JSON] Objects and Arrays” (*), and most JSON usage examples focus on that: for example, how...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
I’m not sure if this remains an open issue or not, but I figured it might help to have a minimal project with an obvious use-case. So I’ve cut down a project I’m working on here to be as small as I can make it.
I want to make a library API. Where users can add Books, which have a ManyToMany relationship with Authors. A book may have multiple Authors, and an Author may write multiple books, so if we serialize a book to JSON and include all of the information about all of its Authors, and then we serialize all of those, and then they all have information about their Books, so then we serialize all those…
An Author is very simple, the name of the author is the ID. That’s it. A Book is an ID, and a title. They have a ManyToMany relationship between them.
So we could POST a book like this, which would make a book, and map it to an author, which we may already have in the database, or which we might be making from her scratch:
Works great! But then we would need to make one HTTP request per book, which could incur a performance constraint. So we want to have another endpoint for adding lots of them:
Unfortunately this will be a problem, because Jackson will deserialize the two “JK Rowling” separately, and bomb out, and even though they are the exact same object, Jackson doesn’t understand how to map them together. My solution was to have the two objects simply resolve to be the same thing. The exact same object reference.
In the Entity:
The ObjectIdResolver class:
I’ll upload the final project code in a sec here.
You can send your QUESTIONS to mailings lists. Issue trackers are for reporting problems and requesting new features.