Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why jackson is serializing transient member also?

I am serializing a POJO into JSON using Jackson 2.1.4 but I want to ignore a particular field from getting serialized. I used transient but still it is serializing that element.

public class TestElement {

    int x;

    private transient String y;

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public String getY() {
        return y;
    }

    public void setY(String y) {
        this.y = y;
    }
}

I am serializing as following:

public static void main(String[] args) throws JsonProcessingException {
    TestElement testElement = new TestElement();
    testElement.setX(10);
    testElement.setY("adasd");
    ObjectMapper om = new ObjectMapper();
    String serialized = om.writeValueAsString(testElement);
    System.err.println(serialized);
}

Please don't suggest @JsonIgnore as I don't want to tie my model to jackson specific annotations. Can it be done using transient only? Is there any API on objectmapper for visibility settings?

like image 936
Naman Avatar asked Feb 13 '14 04:02

Naman


People also ask

Does Jackson ignore transient fields?

If this is your first foray into Spring Boot with Hibernate, you may notice that you are not getting all the properties serialized from your POJOs. Specifically, fields with Hibernate's `@Transient` annotation are ignored during serialization.

Why are transient variables not serialized?

In case you define any data member as transient, it will not be serialized. This is because every field marked as transient will not be serialized. You can use this transient keyword to indicate the Java virtual machine (JVM) that the transient variable is not part of the persistent state of an object.

Does Jackson require serializable?

Note that Jackson does not use java. io. Serializable for anything: there is no real value for adding that. It gets ignored.

Does Jackson use fields or getters?

Jackson uses the setter and getter methods to auto-detect the private field and updates the field during deserialization. Assume you have defined all the fields or properties in your Java class so that both input JSON and output Java class have identical fields.


4 Answers

The reason Jackson serializes the transient member is because the getters are used to determine what to serialize, not the member itself - and since y has a public getter, that gets serialized. If you want to change that default and have Jackson use fields - simply do:

om.setVisibilityChecker(
  om.getSerializationConfig()
    .getDefaultVisibilityChecker()
    .withFieldVisibility(JsonAutoDetect.Visibility.ANY)
    .withGetterVisibility(JsonAutoDetect.Visibility.NONE)
);

Another way to ignore a property on serialization is to do it directly on the class:

@JsonIgnoreProperties(value = { "y" })
public class TestElement {
...

And another way is directly on the field:

public class TestElement {

    @JsonIgnore
    private String y;
...

Hope this helps.

like image 55
Eugen Avatar answered Oct 01 '22 23:10

Eugen


A new way to stop Jackson from serializing and deserializing is to call mapper.configure(MapperFeature.PROPAGATE_TRANSIENT_MARKER, true).

like image 38
manuel Avatar answered Oct 01 '22 23:10

manuel


You can configure it with springs properties

spring.jackson.mapper.propagate-transient-marker=true
like image 29
Carlos Cuesta Avatar answered Oct 02 '22 00:10

Carlos Cuesta


I can't make comments so complete the previous response here, changing the (now) deprecated method setVisibilityChecker and adding a missing clause for booleans:

mapper.setVisibility(
    mapper.getSerializationConfig().
    getDefaultVisibilityChecker().
    withFieldVisibility(JsonAutoDetect.Visibility.ANY).
    withGetterVisibility(JsonAutoDetect.Visibility.NONE).
    withIsGetterVisibility(JsonAutoDetect.Visibility.NONE)
);
like image 20
idelvall Avatar answered Oct 01 '22 22:10

idelvall