Jackson JsonMappingException - No serializer found for class

Jackson JsonMappingException - No serializer found for class

1. Overview

In this article, we will analyze the reason for the Jackson JsonMappingException - No serializer found for class and no properties discovered to create BeanSerializer (to avoid exception, disable FAIL_ON_EMPTY_BEANS).

2. Jackson JsonMappingException

By default, the ObjectMapper of Jackson library can serialize the Java fields that satisfies any of the below two conditions:

  1. public
  2. public getter method

If your Java field contains access modifier other than public or doesn’t have a public getter method, then serialization won’t work.

For example, the below Student class contains id and studentName fields. Both of them are private.

public class Student {
	public Student(long id, String studentName) {
		this.id = id;
		this.studentName = studentName;
	}
	public Student() {	}
	private long id;
	private String studentName;
	@Override
	public String toString() {
		return "Student [id=" + id + ", studentName=" + studentName + "]";
	}
}
@Test
void privateFields_serialize_withoutSetterOrGetter() throws JsonMappingException, JsonProcessingException {
    ObjectMapper mapper = new ObjectMapper();
    Student student = new Student();
    String studentStr = mapper.writeValueAsString(student);
    System.out.println(studentStr);
}

If you serialize the Student object, then it would throw the following error:

com.fasterxml.jackson.databind.JsonMappingException: No serializer found for class com.tedblob.jackson.examples.models.Student and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS)
(or) 
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class com.tedblob.jackson.examples.models.Student 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)

3. Add Getter method with public visibility to fix Jackson JsonMappingException

You can add getter method to your private fields to fix this error.

private long id;
public long getId() {
	return id;
}

4. Change Java field visibility at class level

You can also customize this behavior by using the @JsonAutoDetect annotation. You can set the field visibility as Visibility.ANY:

@JsonAutoDetect(fieldVisibility = Visibility.ANY)

Setting this @JsonAutoDetect with Visibility.ANY annotation would make the Jackson auto-detect fields with any access modifier from private to public.

The below Employee class has the private fields id and name without getter methods. However, Visibility ANY allows Jackson to auto-detect these private fields.

@JsonAutoDetect(fieldVisibility = Visibility.ANY)
public class Employee {
	private long id;
	private String name;
	@Override
	public String toString() {
		return "Employee [id=" + id + ", name=" + name + "]";
	}
}
@Test
void privateFields_serialize_withVisibilityAny() throws JsonMappingException, JsonProcessingException {
	ObjectMapper mapper = new ObjectMapper();
	Employee employee = new Employee();
	String employeeStr = mapper.writeValueAsString(employee);
	System.out.println(employeeStr);
 /* prints {"id":0,"name":null} */
}

5. Change Java field visibility globally

Alternatively, you can also make the Jackson auto-detect fields with any access modifiers by configuring the ObjectMapper:

ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);

The below code contains the ObjectMapper instance whose field visibility is set to ANY. So Jackson detects the id field and then deserializes the JSON to the Student object.

@Test
void privateFields_serialize_withoutSetterOrGetter_Visibility() throws JsonMappingException, JsonProcessingException {
	ObjectMapper mapper = new ObjectMapper();
	mapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);
	Student student = new Student(101, "Jack");
	String studentStr = mapper.writeValueAsString(student);
	System.out.println(studentStr);
}

6. Ignore Jackson JsonMappingException FAIL_ON_EMPTY_BEANS

Jackson throws FAIL_ON_EMPTY_BEANS exception when it cannot serialize the provided Java object. This happens when the Java object doesn’t have any accessors or annotations to show that it can be serialized.

However, you can disable this behavior by configuring the mapper to disable the FAIL_ON_EMPTY_BEANS error. Running the below code simply returns empty JSON {} throwing no exception.

@Test
void privateFields_serialize_FailOnBeans() throws JsonMappingException, JsonProcessingException {
	ObjectMapper mapper = new ObjectMapper();
	mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
	Student student = new Student();
	String studentStr = mapper.writeValueAsString(student);
	System.out.println(studentStr); 
/* prints {} */
}

7. Conclusion

To sum up, we have analyzed the root cause of JsonMappingException - No serialized found for the class. We have also seen the different solutions to fix the error.

Leave a Reply

Your email address will not be published.