Let's get started with a Microservice Architecture with Spring Cloud:
Resolving Exception: Cannot Deserialize From Object Value (No Delegate- Or Property-Based Creator)
Last updated: September 14, 2026
1. Introduction
Jackson is a Java library commonly used to convert between Java objects and JSON. During JSON deserialization, Jackson may throw an InvalidDefinitionException when it can’t determine how to create an instance of the target class. This can happen even when the JSON structure matches the class fields.
In this tutorial, we’ll reproduce the exception using Jackson 2.17.2 and explore several ways to resolve it.
2. Reproducing the Exception
Let’s start with an immutable Notification class that contains a parameterized constructor:
public class Notification {
private final String message;
private final int priority;
public Notification(String message, int priority) {
this.message = message;
this.priority = priority;
}
// getters
}
Next, let’s try to deserialize a JSON object into the Notification class:
String json = "{\"message\":\"Server maintenance\",\"priority\":2}";
ObjectMapper mapper = new ObjectMapper();
mapper.readValue(json, Notification.class);
Although the JSON properties match the fields in Notification, Jackson can’t determine how they map to the constructor parameters. The constructor doesn’t specify which JSON property Jackson should use for each parameter.
As a result, deserialization fails with an InvalidDefinitionException:
Cannot construct instance of `com.baeldung.invaliddefinitionexception.Notification` (no Creators, like default constructor, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
The exception indicates that Jackson needs a suitable mechanism to create the Notification instance. We can address this in several ways.
3. Adding a Default Constructor
One way to resolve the exception is to provide a no-argument constructor:
public class NotificationWithDefaultConstructor {
private String message;
private int priority;
public NotificationWithDefaultConstructor() {
}
// getters and setters
}
By default, Jackson relies on a no-argument constructor to instantiate the target class. It can then populate the object’s properties during deserialization:
NotificationWithDefaultConstructor notification = objectMapper.readValue(json, NotificationWithDefaultConstructor.class);
assertEquals("Server maintenance", notification.getMessage());
assertEquals(2, notification.getPriority());
This approach works well for mutable classes, where Jackson can set the properties after creating the instance.
4. Defining a Property-Based Creator
For immutable classes, we can explicitly define how Jackson should use the parameterized constructor:
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
public class NotificationWithCreator {
private final String message;
private final int priority;
@JsonCreator
public NotificationWithCreator(
@JsonProperty("message") String message,
@JsonProperty("priority") int priority) {
this.message = message;
this.priority = priority;
}
// getters
}
In this case, the @JsonCreator annotation tells Jackson to use the annotated constructor to create the object. The @JsonProperty annotations specify which JSON property corresponds to each constructor parameter.
With the constructor configured as a creator, we can deserialize the JSON while keeping the class immutable:
NotificationWithCreator notification = objectMapper.readValue(json, NotificationWithCreator.class);
assertEquals("Server maintenance", notification.getMessage());
assertEquals(2, notification.getPriority());
In addition, we should make sure to import the annotations from the com.fasterxml.jackson.annotation package, which Jackson 3.x also uses. Jackson won’t recognize creator annotations imported from the legacy org.codehaus.jackson package.
4.1. Factory Methods as Creators
Factory methods can also be creators. If Jackson doesn’t recognize our factory method as a creator, it will throw the same InvalidDefinitionException.
To resolve the issue, we annotate the method and its parameters in the same way as we do with parameterized constructors:
@JsonCreator
public static NotificationWithFactory create(
@JsonProperty("message") String message,
@JsonProperty("priority") int priority) {
return new NotificationWithFactory(message, priority);
}
Now, this method can also act as a creator.
5. Discovering Constructor Parameter Names
Finally, instead of adding Jackson annotations to the target class, we can configure Jackson to discover constructor parameter names.
5.1. Using ParameterNamesModule
In Jackson 2.x, we can use ParameterNamesModule to discover constructor parameter names without adding @JsonProperty annotations:
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new ParameterNamesModule());
Notification notification = mapper.readValue(json, Notification.class);
assertEquals("Server maintenance", notification.getMessage());
assertEquals(2, notification.getPriority());
We need to compile the class with the Java -parameters option so that the parameter names are available at runtime. In Jackson 3.x, this functionality is built into jackson-databind and enabled by default, so we don’t need to register a separate module.
5.2. Using ParanamerModule
Another option in Jackson 2.x is to use ParanamerModule. First, we need to add the jackson-module-paranamer dependency to our project:
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-paranamer</artifactId>
<version>${jackson.version}</version>
</dependency>
Next, we register ParanamerModule with the ObjectMapper:
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new ParanamerModule());
Notification notification =
mapper.readValue(json, Notification.class);
assertEquals("Server maintenance", notification.getMessage());
assertEquals(2, notification.getPriority());
Once registered, ParanamerModule gives Jackson the constructor parameter names, so it can match the message and priority to the corresponding JSON properties.
However, Paranamer is discontinued and supports Jackson 2.x only, which limits this approach for newer projects.
6. Conclusion
In this article, we reproduced a Jackson deserialization exception that occurs when Jackson can’t determine how to create the target object. We then explored several approaches to resolve it.
These include adding a default constructor, defining a property-based creator with @JsonCreator and @JsonProperty, and letting Jackson discover constructor parameter names. Static factory methods can also serve as creators.
The code backing this article is available on GitHub. Once you're logged in as a Baeldung Pro Member, start learning and coding on the project.
















