How to solve Jackson InvalidDefinitionException on immutable objects
Tags: java, tutorial, todayilearned, coding
Published: 2021-02-05 18:01:21

---
title: How to solve Jackson InvalidDefinitionException on immutable objects
published: true
description: 
tags: java, tutorial, todayilearned, coding
cover_image: https://iuriimednikov.com/wp-content/uploads/2021/02/how_to_solve_jackson_with_immutables-1024x576.jpg,
canonical_url: https://iuriimednikov.com/how-to-solve-jackson-invaliddefinitionexception-on-immutable-objects/
---

In my practice, I faced an issue, when while I was working with the Spring framework and I have an immutable object, I got __InvalidDefinitionException__ during web layer tests. That is due to tge fact, that Jackson by default uses a no-args constructor and setters to deserialize an entity from a JSON payload. And surely, this practice leads to bad software design. So, if you also want to solve this problem, let me provide you my solution.

To start, let take a look on my entity model. Observe the following code snippet below:

```java
@Value
@Document(collection = "customers")
public class CustomerModel {
    @Id String customerId;
    String companyName;
    String companyEmail;
    String taxId;
    AddressModel billingAddress;
    AddressModel shippingAddress;

}
```

Here, you can note, that I use the [__@Value__](https://projectlombok.org/features/Value) annotation here in order to get:

- All arguments constructor
- All fields are private and final
- No setters

Using this entity class within a web layer of the application does not lead to problems, and a serialization works as expected when you call the API, for instance, with an external client. However, when I write tests to assert the web layer, I will end with an exception, because, as I have said already, Jackson can not deserialize JSON without a no-args constructor and setters:

![](https://iuriimednikov.com/wp-content/uploads/2021/02/spring-invaliddefinitionexception-output.png)

The first solution, that I have found on [Stackoverflow](https://stackoverflow.com/questions/53191468/no-creators-like-default-construct-exist-cannot-deserialize-from-object-valu/53192674) is to create a  __lombok.config__ file in the root of my project with following parameters:

```
lombok.anyConstructor.addConstructorProperties=true
```

Although, this did not solve the issue. And if you are still reading this post, that means, that this solution also fails for you. What I found as a working approach is to create manually an all-args constructor and annotate it for Jackson, like it is shown in the code snippet below:

```java
@Value
@Document(collection = "customers")
public class CustomerModel {

    @Id String customerId;
    String companyName;
    String companyEmail;
    String taxId;
    AddressModel billingAddress;
    AddressModel shippingAddress;

    @JsonCreator
    public CustomerModel(
            @JsonProperty("customerId") String customerId, 
            @JsonProperty("companyName") String companyName, 
            @JsonProperty("companyEmail") String companyEmail, 
            @JsonProperty("taxId") String taxId, 
            @JsonProperty("billingAddress") AddressModel billingAddress, 
            @JsonProperty("shippingAddress") AddressModel shippingAddress) {
        this.customerId = customerId;
        this.companyName = companyName;
        this.companyEmail = companyEmail;
        this.taxId = taxId;
        this.billingAddress = billingAddress;
        this.shippingAddress = shippingAddress;
    }

}
```

Basically, I use here two annotations:

- __@JsonCreator__ marks a constructor to be explicitly used by Jackson for deserialization
- __@JsonProperty__ is used on constructor's arguments to help Jackson access [concrete fields in runtime](https://stackoverflow.com/questions/21920367/why-when-a-constructor-is-annotated-with-jsoncreator-its-arguments-must-be-ann)

This code perfectly works for me. By the way, don't forget to follow these steps on your nested objects too, if you have them. And I hope, it will help you too.

If you have issues with the Spring Boot that you don't know how to overcome, don't hesitate to [contact me](https://iuriimednikov.com/about/).