364

I get the an exception when trying to serialize a very simple object using Jackson. The error:

org.codehaus.jackson.map.JsonMappingException: No serializer found for class MyPackage.TestA and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS) )

Below is the simple class and code to serialize.

Can anyone tell my why I get this error?

public class TestA {
    String SomeString = "asd";
}

TestA testA = new TestA();
ObjectMapper om = new ObjectMapper();
try {
    String testAString = om.writeValueAsString(testA); // error here!

    TestA newTestA = om.readValue(testAString, TestA.class);
} catch (JsonGenerationException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} catch (JsonMappingException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}
Ted
  • 19,727
  • 35
  • 96
  • 154
  • 1
    I wrote a post about [How to Write a Custom Serializer with Jackson](https://spin.atomicobject.com/2016/07/01/custom-serializer-jackson/?utm_source=stack-overflow-ao&utm_medium=referral&utm_campaign=custom-serializer-jackson) that may be helpful to some. – Sam Berry Jul 01 '16 at 15:04

24 Answers24

440

As already described, the default configuration of an ObjectMapper instance is to only access properties that are public fields or have public getters/setters. An alternative to changing the class definition to make a field public or to provide a public getter/setter is to specify (to the underlying VisibilityChecker) a different property visibility rule. Jackson 1.9 provides the ObjectMapper.setVisibility() convenience method for doing so. For the example in the original question, I'd likely configure this as

myObjectMapper.setVisibility(JsonMethod.FIELD, Visibility.ANY);

For Jackson >2.0:

myObjectMapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);

For more information and details on related configuration options, I recommend reviewing the JavaDocs on ObjectMapper.setVisibility().

voliveira89
  • 1,134
  • 2
  • 9
  • 22
Programmer Bruce
  • 64,977
  • 7
  • 99
  • 97
  • 61
    This worked for me. As of Jackson 2.0, ObjectMapper#setVisibility takes a PropertyAccessor as the first argument. The equivalent oneliner is `myObjectMapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);` – Dan Robinson Mar 28 '13 at 05:26
  • @DanRobinson I used same. But actually I am generating yaml file. so for the JSONString as : `{"term":{"call_failed":"true"}}` it is generating yaml structure as: `filter: map: term: map: call_failed: "true"` Why it is generating `map` keyword? How can I remove it ? – Manish Kumar Aug 03 '16 at 13:32
  • 8
    I probably spent 8 hours with this error, not realizing that my getter method did not have "public" on it..so stupid – Mike Kellogg Nov 23 '16 at 15:26
  • 1
    I am getting this error while converting ClientResponse to string using object mapper – VedantK May 24 '17 at 14:03
  • 6
    You can also add the annotation `@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)` above your class – veben Oct 10 '19 at 07:06
141

Add a

getter

and a

setter

and the problem is solved.

Günay Gültekin
  • 4,486
  • 8
  • 33
  • 36
92

For Jackson to serialize that class, the SomeString field needs to either be public (right now it's package level isolation) or you need to define getter and setter methods for it.

Nathan
  • 8,093
  • 8
  • 50
  • 76
Chris
  • 22,923
  • 4
  • 56
  • 50
  • 5
    Please note this answer is incorrect -- the field does not *need* to be public or have a getter and setter. In another answer to this question, I provided an alternative configuration that does not require changes to the original data structure to be (de)serialized. – Programmer Bruce Feb 28 '13 at 03:45
  • 10
    The answer is useful, even if not 100% precisely correct. I'd forgotten to put 'public' on my vars, and this pointed that out. Thanks! – ChrisPhoenix Apr 17 '15 at 03:08
39

The problem in my case was Jackson was trying to serialize an empty object with no attributes nor methods.

As suggested in the exception I added the following line to avoid failure on empty beans:

For Jackson 1.9

myObjectMapper.configure(SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS, false);

For Jackson 2.X

myObjectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);

You can find a simple example on jackson disable fail_on_empty_beans

Nathan
  • 8,093
  • 8
  • 50
  • 76
Martín C
  • 1,027
  • 1
  • 9
  • 13
10

I had the same problem for a child class where I had control, object mapper was in a common module and was inaccessible. I solved it by adding this annotation for my child class whose object was to be serialized.

@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)
Pavan Kumar
  • 4,182
  • 1
  • 30
  • 45
9

Jackson uses getters and setters serialization./deserialization. So add getter and setter in your model class.

Nakesh
  • 546
  • 2
  • 7
  • 8
8

This error is also thrown if you forget to add the .build() method onto your return status.

return Response.status(Status.OK);         // fails
return Response.status(Status.OK).build(); // works

I got the following error without build() method:

org.codehaus.jackson.map.JsonMappingException: No serializer found for class com.sun.jersey.core.spi.factory.ResponseBuilderImpl
patrics
  • 788
  • 6
  • 15
8

If you can edit the class containing that object, I usually just add the annotation

import com.fasterxml.jackson.annotation.JsonIgnore;

@JsonIgnore 
NonSerializeableClass obj;
ZiglioUK
  • 2,573
  • 4
  • 27
  • 32
  • 2
    This error fires also when your class has a method with name starting with get... For example NonSerializableClass getMyNonSerializableObject(). Jackson tries to serialise it and fails. To resolve this problem just add @JsonIgnore or rename the method. – Alexey Podlasov Nov 16 '15 at 18:39
  • 1
    Used the older version: `org.codehaus.jackson.annotate.JsonIgnore` – AlikElzin-kilaka Jan 06 '16 at 09:47
7

SpringBoot2.0 ,I resolve it by follow code:

@Bean public ObjectMapper objectMapper() {
 return new ObjectMapper().disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);}
Janus
  • 71
  • 1
  • 2
  • 1
    you should keep your model has getter and setter methods. – Janus Sep 08 '18 at 09:59
  • 2
    Welcome to SO! Thanks for contributing. Please add an explanation to your answer, so it's clear what the code does, why it works and how it answers OPs question. – Max Vollmer Sep 08 '18 at 10:07
  • This helped me! But in my opinion, you should inject the ObjectMapper of the context and configure it afterward rather than creating a new one. – RoBeaToZ Aug 28 '19 at 09:31
5

I found at least three ways of doing this:

  1. Add public getters on your entity that you try to serialize;
  2. Add an annotation at the top of the entity, if you don't want public getters. This will change the default for Jackson from Visbility=DEFAULT to @JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY) where any access modifiers are accepted;
  3. Change your ObjectMapper globally by setting objectMapperInstance.setVisibility(JsonMethod.FIELD, Visibility.ANY);. This should be avoided if you don't need this functionality globally.

Choose based on your needs.

georger
  • 1,568
  • 21
  • 24
4

I had a similar problem with lazy loading via the hibernate proxy object. Got around it by annotating the class having lazy loaded private properties with:

@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
N. berouain
  • 1,181
  • 13
  • 17
3

For Oracle Java applications, add this after the ObjectMapper instantiation:

mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
Nathan
  • 8,093
  • 8
  • 50
  • 76
LEMUEL ADANE
  • 8,336
  • 16
  • 58
  • 72
3

Here are the three options:

  1. Data/class that's been accessed needs to be public
  2. If not public, add getters & setters
  3. Or add @JsonIgnore("context")
anothernode
  • 5,100
  • 13
  • 43
  • 62
2

The problem may be because you have declared variable as private. If you change it to public, it works.

Better option is to use getter and setter methods for it.

This will solve the issue!

Nathan
  • 8,093
  • 8
  • 50
  • 76
2

Please use this at class level for the bean:

@JsonIgnoreProperties(value={"hibernateLazyInitializer","handler","fieldHandler"})
2

I just had only getters , after adding setters too , problems resolved.

2

Adding a getter/setter solved this problem for me. either manually add getter/setter or use Lombok annotations @Getter/@Setter/@Data for the same.

Sumit Jadiya
  • 637
  • 6
  • 7
2

Add this in your application properties file

spring.jackson.serialization.FAIL_ON_EMPTY_BEANS=false
Codemaker2015
  • 12,190
  • 6
  • 97
  • 81
hiten
  • 21
  • 2
1

adding setter and getter will also solve the issue as it fixed for me. For Ex:

public class TestA {
    String SomeString = "asd";

    public String getSomeString () {        return SomeString ;     }

    public void setSomeString (String SS ) {        SomeString = SS ;   } 
}
David
  • 2,602
  • 1
  • 18
  • 32
0

Though I added getters and setters I was getting the same error. Later I found a bug, that is by Sonar's advice I cgahnged the getters and setters as protected which was causing the issue. Once I fixed that it worked as exppected.

yellow
  • 425
  • 7
  • 20
0

in spring boot 2.2.5

after adding getter and setter

i added @JsonIgnore on top of the field.

saba
  • 332
  • 2
  • 14
0

If you use Lomdok libraray (https://projectlombok.org/) then add @Data (https://projectlombok.org/features/Data) annotation to your data object class.

Andriy Kryvtsun
  • 3,220
  • 3
  • 27
  • 41
0

For me, the problem was the annotation @RestResource(exported = false) from the import org.springframework.data.rest.core.annotation.RestResource. Which I forgot to remove.

Also, I got the same error when I forgot to add the class annotation @XmlRootElement from the import javax.xml.bind.annotation.XmlRootElement.

j.xavier.atero
  • 506
  • 2
  • 10
  • 25
0

I solved with @Getter from lombok

Sham Fiorin
  • 403
  • 4
  • 16