Tag Archives: InvalidDefinitionException

[Solved] com.fasterxml.jackson.databind.exc. InvalidDefinitionException: No serializer found for class ABC and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS)


InvalidDefinitionException is an intermediate exception which is used as the base class for all JsonMappingExceptions that occurred due to problems with target type definition. Generally a problem with properties or annotations used on a class.

Exception Example

Here this InvalidDefinitionException is occurring because of StudentDetail class is not having any getter and setters.  That’s what while the time of deserialization found bean as empty.

public class StudentDetail {
	private int rollNumber;
	private String firstName;
	private String lastName;
	public StudentDetail(int rollNumber, String firstName, String lastName) {
		super();
		this.rollNumber = rollNumber;
		this.firstName = firstName;
		this.lastName = lastName;
	}
import java.io.IOException;

import com.fasterxml.jackson.databind.ObjectMapper;

public class TestJacksonExample3 {

	public static void main(String[] args) {

		try
		{
		StudentDetail student=new StudentDetail(10011,"Saurabh","Gupta");
	    ObjectMapper mapper = new ObjectMapper();
	    //convert java object to JSON
	    String json=mapper.writeValueAsString(student);
	    System.out.println(json);
		}
		catch(IOException ex)
		{
			ex.printStackTrace();
		}
		catch(Exception ex)
		{
			ex.printStackTrace();
		}

	}

}

Exception Stacktrace


com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class com.fiot.json.jackson.exceptions.StudentDetail and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS)
    at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:77)
    at com.fasterxml.jackson.databind.SerializerProvider.reportBadDefinition(SerializerProvider.java:1191)
    at com.fasterxml.jackson.databind.DatabindContext.reportBadDefinition(DatabindContext.java:313)
    at com.fasterxml.jackson.databind.ser.impl.UnknownSerializer.failForEmpty(UnknownSerializer.java:71)
    at com.fasterxml.jackson.databind.ser.impl.UnknownSerializer.serialize(UnknownSerializer.java:33)
    at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._serialize(DefaultSerializerProvider.java:480)
    at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:319)
    at com.fasterxml.jackson.databind.ObjectMapper._configAndWriteValue(ObjectMapper.java:3905)
    at com.fasterxml.jackson.databind.ObjectMapper.writeValueAsString(ObjectMapper.java:3219)
    at com.fiot.json.jackson.exceptions.TestJacksonExample3.main(TestJacksonExample3.java:17)

Solutions

There is a couple of solution to resolve this issue:

  1. If you have the option to edit source, add getter and setter of properties of the class.
  2. On class, level add annotation @JsonAutoDetect(fieldVisibility = Visibility.ANY) to StudentDetail class to resolve this issue.
    @JsonAutoDetect(fieldVisibility = Visibility.ANY)
    public class StudentDetail {
    	private int rollNumber;
    	private String firstName;
    	private String lastName;
    	public StudentDetail(int rollNumber, String firstName, String lastName) {
    		super();
    		this.rollNumber = rollNumber;
    		this.firstName = firstName;
    		this.lastName = lastName;
    	}
    
  3. We can resolve this issue by setting configuring of ObjectMapper visibility for fields as Visibility.ANY.
    try
    	{
    	StudentDetail student=new StudentDetail(10011,"Saurabh","Gupta");
    	ObjectMapper mapper = new ObjectMapper();
    	mapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);
    	//convert java object to JSON
    	String json=mapper.writeValueAsString(student);
    	System.out.println(json);
    		}
    		catch(IOException ex)
    		{
    			ex.printStackTrace();
    		}
    		catch(Exception ex)
    		{
    			ex.printStackTrace();
    		}
    
    	}
    

You would like to see

Follow below link to learn more on JSON and  JSON issues solutions:

[Solved] com.fasterxml.jackson.databind.exc. InvalidDefinitionException: Cannot construct instance of `XYZ` (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator)


InvalidDefinitionException is intermediate exception which is used as the base class for all JsonMappingExceptions that occurred due to problems with target type definition. Generally a problem with properties or annotations used on a class.

Example of InvalidDefinitionException

In this given example deserialing String JSON to Student object. Here Student class is not having default constructor that’s causing issue as “No able to construct object as no default constructor found”


public class Student {
private int rollNumber;
private String firstName;
private String lastName;

public Student(int rollNumber, String firstName, String lastName)
{
this.rollNumber=rollNumber;
this.firstName=firstName;
this.lastName=lastName;
}
// getter and setter of class
}
import java.io.IOException;

import com.fasterxml.jackson.databind.ObjectMapper;

public class TestJacksonExample {

public static void main(String[] args) {

   String json="{\"rollNumber\":21 , \"firstName\":\"Saurabh\" , \"lastName\":\"Gupta\"}";

try
{
   ObjectMapper mapper = new ObjectMapper();
   Student student= mapper.readValue(json, Student.class);
   System.out.println(student);
}
catch(IOException ex)
{
ex.printStackTrace();
}
catch(Exception ex)
{
ex.printStackTrace();
}

}

Stacktrace of InvalidDefinitionException


com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `com.fiot.json.jackson.exceptions.Student` (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
 at [Source: (String)"{"rollNumber":21 , "firstName":"Saurabh" , "lastName":"Gupta"}"; line: 1, column: 2]
    at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:67)
    at com.fasterxml.jackson.databind.DeserializationContext.reportBadDefinition(DeserializationContext.java:1452)
    at com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1028)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1297)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:326)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:159)
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4013)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3004)
    at com.fiot.json.jackson.exceptions.TestJacksonExample.main(TestJacksonExample.java:18)

Solutions

To solution of this issue just add a default constructor as below


public class Student {
	private int rollNumber;
	private String firstName;
	private String lastName;
        //default constructor
	public Student()
	{
	 super();
	}
	public Student(int rollNumber, String firstName, String lastName)
	{
		this.rollNumber=rollNumber;
		this.firstName=firstName;
		this.lastName=lastName;
	}
	// getter and setter of class
	}
	

Note:

Jackson looks for POJO class for deserialization. As per definition of POJO (Plain Old Java Object) is the class with out any restriction, having getter and setter methods, if required can also implement object class methods like equals(), toString() etc.

You would like to see

Follow below link to see more JSON issues solutions:

JSON Issues Solutions

References

https://fasterxml.github.io/jackson-databind/javadoc/2.9/com/fasterxml/jackson/databind/exc/InvalidDefinitionException.html

[Solved] com.fasterxml.jackson.databind.exc. InvalidDefinitionException: Cannot construct instance of `XYZ` (no Creators, like default construct, exist): abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information


InvalidDefinitionException is an intermediate exception which is used as the base class for all JsonMappingExceptions that occurred due to problems with target type definition. Generally a problem with properties or annotations used on a class.

Example of InvalidDefinitionException

Here Publication class is abstract that’s causing issues because we can’t directly create an instance of an abstract class. Here at the time  of JSON deserialization to author object not able to create an instance of Publication class.

public class Author {
	  private String name;
	  public Publication publication;

	  public Author()
	  {

	  }

	  //getter and setter of properties
	}

	public abstract class Publication {
	public String title;

	public Publication() {

	}
	// getter and setter of properties
}
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
<span id="mce_SELREST_start" style="overflow: hidden; line-height: 0;"></span>
public abstract class Publication {
	public String title;

	public Publication() {

	}
	// getter and setter of properties
}
import java.io.IOException;

import com.fasterxml.jackson.databind.ObjectMapper;

public class TestJacksonExample {

public static void main(String[] args) {
String json = "{\"name\":\"Saurabh Gupta\",\"publication\":{\"title\":\"Facing Issues On IT\",\"type\":\"Drama\" }}";

try
{
   ObjectMapper mapper = new ObjectMapper();
   Author author= mapper.readValue(json, Author.class);
   System.out.println(author);
}
catch(IOException ex)
{
ex.printStackTrace();
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
}

Stacktrace of InvalidDefinitionException


com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `com.fiot.json.jackson.exceptions.Publication` (no Creators, like default construct, exist): abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information
 at [Source: (String)"{"name":"Saurabh Gupta","publication":{"title":"Facing Issues On IT"}}"; line: 1, column: 39] (through reference chain: com.fiot.json.jackson.exceptions.Author["publication"])
    at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:67)
    at com.fasterxml.jackson.databind.DeserializationContext.reportBadDefinition(DeserializationContext.java:1452)
    at com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1028)
    at com.fasterxml.jackson.databind.deser.AbstractDeserializer.deserialize(AbstractDeserializer.java:265)
    at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:129)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:288)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:151)
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4013)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3004)
    at com.fiot.json.jackson.exceptions.TestJacksonExample.main(TestJacksonExample.java:17)

Solutions

As a solution to the current issue, Not declare Publication class as abstract because we can’t directly create an instance of an abstract class only allowed instance through subclass. 

Recommend Solution

We can solve this problem by using simple @JsonDeserialize on the abstract class as mentioned as a subtype.

import com.fasterxml.jackson.databind.annotation.JsonDeserialize;

//@JsonDeserialize(as = Book.class)
public abstract class Publication {
	public String title;

	public Publication() {

	}
	// getter and setter of class
}

If abstract class having more than one subtype, then mentioned all the classes as SubTypes.

@JsonSubTypes(
{
	@Type(value = Book.class, name = "book"),
	@Type(value = Magzine.class, name = "magzine"),
        @Type(value = Comics.class, name = "comics")
})
public abstract class Publication {
}

Note:

Jackson looks for POJO class for deserialization. As per the definition of POJO (Plain Old Java Object) is the class without any restriction, having getter and setter methods, if required can also implement object class methods like equals, toString(), etc.

References

https://fasterxml.github.io/jackson-databind/javadoc/2.9/com/fasterxml/jackson/databind/exc/InvalidDefinitionException.html

You would like to see

Follow below link to learn more on JSON and  JSON issues solutions: