Reputation: 3749
I am trying to Serialize and deserialize a very large object graph. in order to reduce the size of the generated JSON, I thought I would use Jackson's @JsonIdentityInfo annotation, which seems to work well for this particular usecase.
However when I add that it blows up. Hard. Example code follows:
Main.class
@Data
@Builder
@JsonDeserialize(builder = Main.MainBuilder.class)
@JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class)
public class Main {
private final String name;
@Singular
private final Map<String, Main> mains;
public static void main(String[] args) throws IOException {
var test = Main.builder()
.name("Root")
.main("One", Main.builder()
.name("One")
.build())
.main("Two", Main.builder()
.name("Two")
.build())
.main("Three", Main.builder()
.name("Three")
.build())
.build();
var om = new ObjectMapper();
var result = om.writeValueAsString(test);
System.out.println(result);
var back = om.readValue(result, Main.class);
}
@JsonPOJOBuilder(withPrefix = "")
public static class MainBuilder {
}
}
build.gradle
plugins {
id 'java'
id 'application'
}
repositories {
jcenter()
mavenCentral()
}
sourceCompatibility = 11
targetCompatibility = 11
mainClassName = 'dk.acto.Main'
dependencies {
compileOnly 'org.projectlombok:lombok:1.18.0'
implementation 'com.fasterxml.jackson.core:jackson-databind:2.9.7'
annotationProcessor "org.projectlombok:lombok:1.18.0"
}
If you comment out the @JsonIdentityInfo
annotation the code works as expected, and I don't really understand why. Any help is much appreciated.
Upvotes: 1
Views: 1266
Reputation: 2307
It fails when it's deserializing the @id field that was added by the @JsonIdentityInfo
. You need to handle the @id field.
Adding @JsonIgnoreProperties
to your builder will stop it failing.
@JsonPOJOBuilder(withPrefix = "")
@JsonIgnoreProperties(ignoreUnknown=true)
public static class MainBuilder {
}
As would adding the @id to your builder
@JsonPOJOBuilder(withPrefix = "")
public static class MainBuilder {
private int id;
@JsonProperty(value="@id")
public MainBuilder id() {
this.id = id;
return this;
}
}
Upvotes: 1