Flaky behavior of Jackson Deserialization: "No _valueDeserializer assigned"

Viewed 204

I have a problem with Jackson's deserialization mechanism in Spring Boot. My domain classes look like this:

@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class Post {
    // ...

    @ManyToOne
    @JsonIncludeProperties({ "id", "course" })
    private Lecture lecture;

    @ManyToOne
    @JsonIncludeProperties({ "id" })
    private Course course;
}

@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class Lecture {
    // ...
    
    @JsonIgnoreProperties(value = { "lectures", "posts" }, allowSetters = true)
    private Course course;
}

@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class Course {
    // ...

    @JsonIgnoreProperties(value = "course", allowSetters = true)
    private Set<Lecture> lectures = new HashSet<>();

    @JsonIgnoreProperties("course")
    private Set<Post> posts = new HashSet<>();
}

Now to test the creation of Posts which have a Lecture set, I'm trying to test them by using the MockMvc bean. Therefore, I'm doing the following:

  • creating an object of type Post,
  • sending it via an HTTP POST to my RestController, and
  • deserializing the JSON response back to Post.class.

Everything works fine, but step (3) works only approx. 9/10 times (it never fails on my local setup, but only in the CI pipeline, which makes it a very hard to debug flaky test).

Post postToSave = generatePost();
postToSave.setLecture(generateLecture());
Post createdPost = request.postWithResponseBody("/api/post", postToSave, Post.class);

The error log looks like this:

com.fasterxml.jackson.databind.exc.MismatchedInputException: No _valueDeserializer assigned ... (through reference chain: a.b.c.Post["lecture"]->a.b.c.Lecture["course"])
at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:63)
at com.fasterxml.jackson.databind.DeserializationContext.reportInputMismatch(DeserializationContext.java:1575)
at com.fasterxml.jackson.databind.deser.impl.FailingDeserializer.deserialize(FailingDeserializer.java:33)
at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:129)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:402)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:195)
at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:129)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:402)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:195)
at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:322)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4593)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3548)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3516)

I would appreciate any help on this issue.

0 Answers
Related