
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:
- public
- 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.