Mikkel Løkke
Mikkel Løkke

Reputation: 3749

UnrecognizedPropertyException when using Jackson, @JsonIdentityInfo and @JsonDeserialize with a lombok Builder

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

Answers (1)

pcoates
pcoates

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

Related Questions